进程内存

进程内存

组成

进程内存占用主要由以下几部分组成:

  • 自身代码
  • 共享库代码
  • 运行过程中分配的堆和栈
  • 通过mmap映射的磁盘文件内容

虚拟内存与物理内存

物理内存对于进程来说是透明的,进程直接操作的是虚拟内存.进程向操作系统申请内存的时候,分配的是虚拟内存(地址空间),只有当进程使用这部分内存时,操作系统才会将相应的物理内存与相应的虚拟内存关联(缺页中断).

共享内存

从进程来看,虚拟内存是进程独立的,所有内存都是私有的,包括自身代码,共享库,堆栈等.但实际在物理层面很多东西是可以共享的,比如共享库,自身代码,甚至是自身私有的堆栈.

共享库

同一个共享库的代码在物理内存中只存在一份,这块内存会映射到不同进程的虚拟内存中,对进程而言是自己的私有内存,对于操作系统而言,则是节省了内存的资源.

进程的自身代码

当同一个程序运行多个进程时,其自身代码也被共享

进程的私有内存

当从一个进程fork出一个子进程时,那么父进程的私有内存则会与子进程共享,但会被标记为copy-on-write.

进程内存大小的度量方法

VSZ(Virtual Memory Size)

虚拟内存大小,进程运行理论上需要内存的大小,形容进程运行时所需要的总内存大小,包括哪些还没有被加载到实际内存中的代码和数据.

RSS(Resident Set Size)

常驻内存大小(工作集),表示实际使用物理内存的大小,包含了共享库占用的内存,(不包括已经被置换到磁盘的内存)

PSS(Proportional Set Size)

实际使用物理内存大小,比例分配共享库占用的内存,比如用到的某个100K共享库共有2个程序用到,那么被计算为100k/2=50k

USS(Unique Set Size)

进程独占物理内存大小,不包含共享库.

计算示例

假如要度量进程占用的内存大小,较好的选择是使用PSS,用RSS也行,不过要注意有些内存是和别的进程共享的。

再举个例子总结一下前面三个概念,比方一个进程有500K的代码并且链接了2500K的共享库,而后有200K的堆栈分配。其中有400K自身的代码、1000K的共享库以100K的堆栈内存被加载在实际内存(RAM)中,并且系统中一共有两个进程用了同样的共享库。那么:

VSZ:500K + 2500K + 200K = 3200K

RSS:400K + 1000K + 100K = 1500K

PSS:400K + (1000K / 2) + 100K = 1000K

USS: 400K + 100K = 500K