Linux中的内存管理

本文深入探讨了Linux内存管理,包括overcommit机制,介绍了三种overcommit处理模式及其配置,并讲解了smap、proc status和proc meminfo等工具如何展示内存使用情况。通过分析smap输出,解释了各字段含义,如Rss、Pss等,提供了了解和优化内存使用的关键信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内存管理中的overcommit

1.      什么是overcommit

Linux calls this overcommit, which refers to the fact that thekernel allows a process to allocate more memory than is currently available.The kernel is effectively speculating that the memory will be available whenneeded.

     Linux对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。这种技术叫做Overcommit。当linux发现内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。

     当oom-killer发生时,linux会选择杀死哪些进程?选择进程的函数是oom_badness函数(在mm/oom_kill.c中),该函数会计算每个进程的点数(0~1000)。点数越高,这个进程越有可能被杀死。每个进程的点数跟oom_score_adj有关,而且oom_score_adj可以被设置(-1000最低,1000最高)。

 

2.      Linux configure the overcommit

The Linux kernel supports the following overcommit handling modes

0  - Heuristic overcommithandling. Obvious overcommits of address space are refused. Used for a typicalsystem. It ensures a seriously wild allocation fails while allowing overcommitto reduce swap usage.  root is allowed toallocate slighly more memory in this mode. This is the default. (表示检查是否有足够的内存可用,如果是,允许分配;如果内存不够,拒绝该请求,并返回一个错误给应用程序。)

1  -  Alwaysovercommit. Appropriate for some scientific applications. (表示根据vm.overcommit_ratio定义的值,允许分配超出一定内存(物理内存加上交换内存)的请求。vm.overcommit_ratio参数是一个百分比,加上内存量决定内存可以超量分配多少内存。例如,vm.overcommit_ratio值为50,而内存有1GB,那么这意味着在内存分配请求失败前,加上交换内存,内存将允许高达1.5GB的内存分配请求。)

2  -  Don'tovercommit. The total address space commit for the system is not permitted toexceed swap + a configurable percentage (default is 50) of physical RAM. Dependingon the percentage you use, in most situations this means a process will not bekilled while accessing pages but will receive errors on memory allocation as appropriate.(内核允许分配超过所有物理内存和交换空间总和的内存.)

 

Theovercommit policy is set via the sysctl `vm.overcommit_memory'.

 

The overcommit percentage is set via `vm.overcommit_ratio'.

 

Linux内存管理smap

在Linux内核 2.6.16中引入了一个系统内存接口特性,这个接口位于/proc/$pid/目录下的smaps文件中,一看内容发现是进程内存映像信息,比同一目录下的maps文件更详细些。

 

 

400df000-4048c000 r--s 00000000 1f:05286        /data/dalvik-cache/system@framework@core.jar@classes.dex 

Size:               3764 kB 

Rss:                1804 kB 

Pss:                1804 kB 

Shared_Clean:          0 kB 

Shared_Dirty:          0 kB 

Private_Clean:      1804 kB 

Private_Dirty:         0 kB 

Referenced:         1804 kB 

Anonymous:             0 kB 

Swap:                  0 kB 

KernelPageSize:        4 kB 

MMUPageSize:           4 kB 

 

 

以上述输出结果为例:

400df000-4048c000 r--s 00000000 1f:05 286/data/dalvik-cache/system@framework@core.jar@classes.dex

 

Ø  400df000-4048c000: 是该虚拟内存段的开始和结束位置;

Ø  r--s: 内存段的权限,最后一位p代表私有,s代表共享;

Ø  0000000: 该虚拟内存段在对应的映射文件中的偏移量;

Ø  1f:05: 文件的主设备和次设备号;

Ø  286: 被映射到虚拟内存的文件的索引节点号;

Ø  /data/dalvik-cache/system@framework@core.jar@classes.dex: 被映射到虚拟内存的文件名称。后面带(deleted)的是内存数据,可以被销毁;

Ø  Size: 是进程使用内存空间,并不一定实际分配了内存(VSS);

Ø  Rss: 是实际分配的内存(不需要缺页中断就可以使用的);

Ø  Pss: 是平摊计算后的使用内存(有些内存会和其他进程共享,例如mmap进来的);

Ø  Shared_Clean: 和其他进程共享的未改写页面;

Ø  Shared_Dirty: 和其他进程共享的已改写页面;

Ø  Private_Clean: 未改写的私有页面页面;

Ø  Private_Dirty: 已改写的私有页面页面;

Ø  Referenced: 标记为访问和使用的内存大小;

Ø  Anonymous: 不来自于文件的内存大小;

Ø  Swap: 存在于交换分区的数据大小(如果物理内存有限,可能存在一部分在主存一部分在交换分区);

Ø  KernelPageSize: 内核页大小;

Ø  MMUPageSize: MMU页大小,基本和Kernel页大小相同;

 

其中Dirty页面如果没有交换机制的情况下,应该是不能回收的。

精确分析内存占用可以用Private内存信息来衡量。

 

 

Linux内存管理proc status

Develop>cat /proc/24475/status

Name:   netio              可执行程序的名字

State:   R (running)          进程状态

Tgid:   24475                 线程组号

Pid:   24475                  进程id

PPid:   19635                 父进程id

TracerPid:    0 

Uid:   0    0    0   0

Gid:   0    0    0   0

FDSize:   256                 该进程最大文件描述符个数

Groups:   0

VmPeak:    6330708 kB         内存使用峰值

VmSize:     268876 kB          进程虚拟地址空间大小

VmLck:           0 kB          进程锁住的物理内存大小,锁住的物理内存无法交换到硬盘

VmHWM:      16656 kB

VmRSS:      11420 kB          进程正在使用的物理内存大小

VmData:     230844 kB         进程数据段大小

VmStk:         136 kB          进程用户态栈大小

VmExe:         760 kB          进程代码段大小

VmLib:        7772 kB          进程使用的库映射到虚拟内存空间的大小

VmPTE:        120 kB          进程页表大小

VmSwap:           0 kB

Threads:   5

SigQ:   0/63346

SigPnd:   0000000000000000

ShdPnd:   0000000000000000

SigBlk:   0000000000000000

SigIgn:   0000000001000000

SigCgt:   0000000180000000

CapInh:   0000000000000000

CapPrm:   ffffffffffffffff

CapEff:   ffffffffffffffff

CapBnd:   ffffffffffffffff

Cpus_allowed:    01

Cpus_allowed_list:    0

Mems_allowed:    01

Mems_allowed_list:    0

voluntary_ctxt_switches:    201

nonvoluntary_ctxt_switches:    909

 

Linux内存管理proc meminfo

Develop>cat /proc/meminfo

MemTotal:        8112280 kB       所有可用RAM大小 (即物理内存减去一些预留位和内核的二进制代码大小)

MemFree:         4188636 kB       LowFree与HighFree的总和,被系统留着未使用的内存

Buffers:           34728 kB        用来给文件做缓冲大小

Cached:           289740 kB       被高速缓冲存储器(cache memory)用的内存的大小                                 (等于 diskcache minus SwapCache )

SwapCached:            0 kB       被高速缓冲存储器(cache memory)用的交换空间的大小已经被交换出来的内存,但仍然被存放在swapfile中。用来在需要的时候很快的被替换而不需要再次打开I/O端口

Active:           435240 kB       在活跃使用中的缓冲或高速缓冲存储器页面文件的大小,除非非常必要否则不会被移作他用

Inactive:         231512 kB       在不经常使用中的缓冲或高速缓冲存储器页面文件的大小,可能被用于其他途径.

Active(anon):     361252 kB

Inactive(anon):   120688 kB

Active(file):      73988 kB

Inactive(file):   110824 kB

Unevictable:           0 kB

Mlocked:               0 kB

SwapTotal:             0 kB         交换空间的总大小

SwapFree:             0 kB        未被使用交换空间的大小

Dirty:                 0 kB         等待被写回到磁盘的内存大小

Writeback:             0 kB         正在被写回到磁盘的内存大小

AnonPages:        348408 kB        未映射页的内存大小

Mapped:            33600 kB       已经被设备和文件等映射的大小

Shmem:            133536 kB

Slab:              55984 kB        内核数据结构缓存的大小,可以减少申请和释放内存带来的消耗

SReclaimable:      25028 kB         可收回Slab的大小

SUnreclaim:        30956 kB        不可收回Slab的大小(SUnreclaim+SReclaimable=Slab)

KernelStack:        1896 kB         内核栈区大小

PageTables:         8156 kB        管理内存分页页面的索引表的大小

NFS_Unstable:          0 kB        不稳定页表的大小

Bounce:                0 kB

WritebackTmp:          0 kB

CommitLimit:     2483276 kB

Committed_AS:    1804104 kB

VmallocTotal:   34359738367 kB      可以vmalloc虚拟内存大小

VmallocUsed:      565680 kB        已经被使用的虚拟内存大小

VmallocChunk:   34359162876 kB

HardwareCorrupted:     0 kB

HugePages_Total:    1536            大页面数目

HugePages_Free:        0           空闲大页面数目

HugePages_Rsvd:        0

HugePages_Surp:        0

Hugepagesize:       2048 kB        大页面一页大小

DirectMap4k:       10240 kB

DirectMap2M:     8302592 kB

VSS/RSS/PSS/USS

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值