内存

内存

作者:赵坤

内存分配

首先给出 32 位系统虚拟内存空间分布图:

在 C 语言中,内存分配采用 malloc() 函数进行分配。底层实现:

  • 申请的内存小于 128K,使用 brk() 函数完成,也就是从上图中的中分配的内存
  • 申请的内存大于 128K,使用 mmap() 内存映射函数完成,也就是从上图中的文件映射中分配的内存

内存回收

应用程序应通过 free()unmap() 来释放内存。

当然,系统也会监管进程的内存,当发现系统内存不足时,会采取措施:

  • 使用 LRU 算法回收缓存
  • 回收不常访问的内存,写到 Swap 区(位于硬盘上)
  • 杀死进程

查看整个系统的内存

$ free
              total        used        free      shared  buff/cache   available
Mem:        6030036     2312004      266488      624252     3451544     2911700
Swap:       2097148         256     2096892

查看某个进程的内存

使用 topps

$ top
PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                
8883 zk        20   0   16.7g 477004 223504 S   4.7   7.9   2:02.69 chrome                                                                 
2075 zk        20   0 1233356  99568  53584 S   4.0   1.7   4:49.63 Xorg                                                                   
2681 zk        20   0  865052  56464  42040 S   2.7   0.9   0:11.70 gnome-terminal-                                                        
2247 zk        20   0 4335224 252364  99052 S   1.3   4.2   6:50.33 gnome-shell   

Buffer vs Cache

free 命令中的 buff/cache 一列的 buffcache 分别指代什么?

  • buff 即 Buffer,缓存磁盘数据,是对原始磁盘块的缓存,内核可以将分散写改为集中写。
  • cache 缓存从磁盘读取的数据,缓存的是磁盘读取文件的页缓存

内存回收机制

系统可以回收的内存:

  • 文件页(Buffer、Cache、文件映射页)
  • 匿名页(堆内存)

其中,文件页如果被修改过,那么就会变为脏页,必须先写入磁盘,才能内存释放。脏页写入磁盘有两种方式:

  • 调用 fsync() 写入脏页到磁盘
  • 内核线程定期 pdflush 刷新这些脏页到磁盘

而匿名页虽无法直接回收,但是通过 Swap 机制可以将不常用的内存写到磁盘中,然后释放内存,给其他程序用。

通过调节 /proc/sys/vm/swappiness 值(0 - 100)可以控制回收匿名页的优先级,值越大,越优先回收匿名页。