内存

作者: Virtualer | 来源:发表于2019-08-29 17:47 被阅读0次
1. 内核空间和用户空间

在32位的系统下,内存拥有4G(2^32)的寻址能力。大多数操作系统会将4G空间中的一部分给内核使用,应用程序无法直接访问,这块内存称为内核内存空间。

  • Windows系统会将高地址的2G空间分给内核(可配置为1G)
  • Linux默认是将高地址1G空间分给内核

剩余空间按称为用户内存空间。

2. 内存区域
  • 栈:通常在用户内存空间的最高地址处分配,一般数M大小。
  • 堆:通常在栈的低地址方向,也可能内存位置不固定,一般比栈大很多。
  • 可执行文件映像:由装载器在装载时将可执行文件内存读取到此部分位置。
  • 保留区:内存中收到保护而禁止访问的内存区域的总称,例如大多数操作系统中极小的地址是不允许访问的,如指针指向nullptr(NULL)。所以在清理完之后将指针指向nullptr。这里多说一下,在清理指针或者初始化指针的时候尽量使用nullptr/nullptr_t,而不是NULL
  • 动态链接库映射区:用于装载动态链接库,linux中如果可执行文件依赖其它共享库,那么系统会为此文件从0x40000000的地址分配相应空间,载入动态库。
  • 代码段:存储程序执行代码的空间,其大小在程序运行前已经确定,并且通常是只读的状态。某些架构中也允许代码段可写,可修改程序。也有可能存放一些制度的常量。
  • 数据段:存储程序中已经初始化的全局变量的空间。
  • 未初始化数据段(BSS段):存储程序中未初始化或者初始化未0的全局变量和静态变量的空间。
    栈从高到低增长,堆从低到高增长
3. 实现方式

操作系统是通过内存管理器实现内存的申请和划分的,并且负责将虚拟内存地址和物理内存地址映射起来。映射方式是内部的结构体存储指向空间地址。

4. malloc的实现

将内存的处理交给内核去做无疑是可行的,但是系统中存在着无数程序的无数申请和释放内存操作,内核调用的性能消耗是很大的,进而影响应用程序性能。
比较好的做法是程序向操作系统申请空间,由程序自己的运行库去管理,当此处空间被使用完,再根据需要向操作系统申请。

5. Linux的堆管理

Linux下堆分配方式有两种系统调用,bk()和mmap(),分配的都是虚拟内存空间。标准C语言库中的malloc/free进行申请和释放内存,底层都是由brk/mmap/munmap实现的。

  • brk():设置进程数据段的结束地址,可以扩大或者缩小数据段(linux系统中的数据段和BSS段统称数据段)。如果将数据段的结束地址向高地址位移动,那么扩大的部分就可以供程序使用,然后将这部分作为堆使用。
  • mmap():向操作系统申请一块虚拟内存空间,此空间位于文件映射区,就是堆和栈中间。linux中的glibc的malloc是小于128k的空间在现有堆中分配出来,大于128k的空间调用mmap函数分配一块匿名空间,在匿名空间中分配空间。
6. 最大malloc(linux)

最大申请空间受到诸多因素干扰,比如系统限制或者物理内存和交换空间总和等。mmap申请匿名空间时系统会为它在内存或交换空间中预留下地址,但是不能超过空闲内存和空闲交换空间的总和。

7. 堆分配算法
  • malloc
    将堆中各个空闲块根据链表链接。申请空间时遍历查找合适大小,拆分出来;释放空间时则合并进链表中。最后链表存在很多细碎空间,在申请一块大内存时候malloc会请求延时,以便整理细碎空间,合并成一块大内存。
  • 位图
    将堆划分为大量相等的块。申请空间时,分配整倍数的块大小,第一个块称为head,其余称为body,我们可以使用一个整数数组记录块的使用情况。每个块均只有头、主体和空闲三种状态,那么只需要两位就可以表示出来所有块的状态,所以称为位图。
  • 对象池
    将堆空间划分为大小相等的块(与位图类似),它认为某种情况下每次分配的空间都相等,所以每次返回一个块的大小,可以变化为链表或者位图。因为不用每次查找合适的大小内存,所以效率很高。

实际上,堆的分配算法是多种算法复合而成的,并不是单一的算法。

相关文章

  • Linux 内存管理 应用篇

    1、物理内存和虚拟内存 物理内存:物理内存就是系统硬件提供的内存大小,是真正的内存 虚拟内存:为了满足物理内存的不...

  • linux io与zero copy

    1. 物理内存与虚拟内存 1.1 物理内存 物理内存指通过物理内存条而获得的内存空间。 1.2 虚拟内存 虚拟内存...

  • 性能优化<第五篇>:内存优化

    1、为什么要内存优化? 2、了解内存中的内容 3、内存上限 4、GC内存回收机制 5、内存泄漏、内存抖动、内存溢出...

  • JVM第二天-volatile final synchroniz

    1.JAVA内存模型 简单的讲,Java 内存模型将内存分为共享内存和本地内存。共享内存又称为堆内存,指的就是线程...

  • 伙伴算法和slab算法

    0. 内存管理问题 内存碎片太小和管理内存碎片的效率问题 内存碎片:回收内存时,将内存块放入free链表中。因内存...

  • JVM 常见内容汇总

    面试题 对象 对象的创建 分配内存 对象头 内存溢出 内存溢出与内存泄漏 内存溢出:系统无法再分配内存空间。 内存...

  • java内存模型

    1.内存模型(JMM) 1.1什么是Java内存模型? Java内存模型将内存分为主内存和工作内存两大部分;主内存...

  • 变量提升

    堆内存 & 栈内存 JS中的内存一共两种:堆内存和栈内存 堆内存 作用:用来存储引用数据类型值的内存空间叫做堆内存...

  • 物理内存和虚拟内存

    物理内存 物理内存是真实的内存大小,即内存条内存大小 虚拟内存 虚拟内存是为了满足系统对超出物理内存容量的需求时在...

  • 5、哪些情况下会导致oom问题?

    1、根据java的内存模型会出现内存溢出的内存有堆内存、方法区内存、虚拟机栈内存、native方法区内存;2、一般...

网友评论

      本文标题:内存

      本文链接:https://www.haomeiwen.com/subject/jvziectx.html