Mat*_*att 12 linux memory-leaks memory
在 Arch 3.6.7 x86_64 内核上,我试图说明系统的内存使用情况,我越看越有漏洞(在已用内存的计算中,的用法)。
这是一个新启动的系统。除了 systemd 和 sshd 之外没有太多运行以保持简单
$ ps aux | sort -n -k6
...
root 316 0.0 0.0 7884 812 tty1 Ss+ 14:37 0:00 /sbin/agetty --noclear tty1 38400
matt 682 0.0 0.0 24528 820 pts/0 S+ 15:09 0:00 sort -n -k6
dbus 309 0.0 0.0 17280 1284 ? Ss 14:37 0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
matt 681 0.0 0.0 10808 1364 pts/0 R+ 15:09 0:00 ps aux
root 308 0.0 0.0 26060 1516 ? Ss 14:37 0:00 /usr/lib/systemd/systemd-logind
root 148 0.0 0.0 25972 1692 ? Ss 14:37 0:00 /usr/lib/systemd/systemd-udevd
matt 451 0.0 0.0 78180 2008 ? S 14:37 0:00 sshd: matt@pts/0
root 288 0.0 0.0 39612 2708 ? Ss 14:37 0:00 /usr/sbin/sshd -D
matt 452 0.0 0.0 16452 3248 pts/0 Ss 14:37 0:00 -bash
root 1 0.0 0.0 32572 3268 ? Ss 14:37 0:00 /sbin/init
root 299 0.0 0.0 69352 3604 ? Ss 14:37 0:00 /usr/sbin/syslog-ng -F
root 449 0.0 0.0 78040 3800 ? Ss 14:37 0:00 sshd: matt [priv]
root 161 0.0 0.0 358384 9656 ? Ss 14:37 0:00 /usr/lib/systemd/systemd-journald
Run Code Online (Sandbox Code Playgroud)
最详细的内存信息,我能找到的是这个从2007年这似乎已导致除PSS的领域一般内核占一个过程的,但他们的Python代码是老版本的内核,不幸的是一些在/ proc / K *文件从那时起就消失了。在的/ proc / meminfo中的文件也是有帮助的,但老化有点太。
所以,我所看到的演示。
# cat /proc/meminfo
MemTotal: 16345780 kB
MemFree: 16129940 kB
Buffers: 10360 kB
Cached: 48444 kB
SwapCached: 0 kB
Active: 24108 kB
Inactive: 46724 kB
Active(anon): 12104 kB
Inactive(anon): 3616 kB
Active(file): 12004 kB
Inactive(file): 43108 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 11996 kB
Mapped: 16372 kB
Shmem: 3696 kB
Slab: 25092 kB
SReclaimable: 11716 kB
SUnreclaim: 13376 kB
KernelStack: 928 kB
PageTables: 2428 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 8172888 kB
Committed_AS: 34304 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 372788 kB
VmallocChunk: 34359362043 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 12288 kB
DirectMap2M: 16680960 kB
Run Code Online (Sandbox Code Playgroud)
如果我们加起来使用:
MemTotal - MemFree - Buffers - Cached = Used
16345780 - 16129940 - 10360 - 48444 = 157036
Run Code Online (Sandbox Code Playgroud)
所有 Active*/Inactive* 似乎是应用于某些页面(不是全部)的计数器,因此可以复制其他地方的计数。
Active + Inactive = Used
46724 + 24108 = 70832 (not quite)
Run Code Online (Sandbox Code Playgroud)
Commited_AS 似乎与用户空间私有/共享内存的总和密切相关,从 /proc/*/smaps 中扣除共享文件。考虑到PSS也排队。(出于兴趣,我在 32 位 debian 2.6.32-5-686 上得到了一个更大、更大的 Commited_AS)
AnonPages + Mapped + Commited_AS = Userspace?
11996 + 16372 + 34304 = 62672
Run Code Online (Sandbox Code Playgroud)
Slab 与 /proc/slabinfo 内联
Slab + Shmem + KernelStack + PageTables = Kernelspace?
25092 + 3696 + 928 + 2428 = 32144
Userspace? + Kernelspace? = Used?
62672 + 32144 = 94816
Run Code Online (Sandbox Code Playgroud)
所以~63M短。我觉得内核和所有加载的模块都缺少一些 MB。平板似乎覆盖了很多,所以如果有任何遗漏,我不确定这是否等于 ~ 60Mb?
63 有点接近 Active+Inactive 数字,但这感觉不对。
那么有没有人知道神奇的公式?否则,如果我正在查看的数字是正确的,那么我可以查看的内存分配中的灰色区域是什么?
看来 linux 吃了我的 ram!尽管比通常被指控的要少=)
编辑Commited_AS 是内核对覆盖其已提交内容的 99.9% 需要多少内存的猜测,因此不是真正分配的数字。AnonPages+Mapped 是它的一个组成部分,所以留下了一个更大的漏洞,现在大约 100MB。
User + Kernel
28368 + 32144 = 60512 != 157036
Run Code Online (Sandbox Code Playgroud)
AnonPages 和 Mapped 主要使用来自 /proc/[0-9]*/smaps wgen 的匿名/映射信息进行跟踪,同时将 PSS/Shared 考虑在内。
保留区域似乎都适合从总内存中取出的块:
总free
内存为 16345032Kb
总系统内存为 16777216Kb PCI'hole
' - lspci -v
266520K = 16510696K
Bios Reserved - dmesg
92793K = 16417903K
edit2
我注意到这个额外的内存使用量不在原来的机器内运行的虚拟机上/proc/meminfo
。所以我开始四处寻找两者之间的不同之处。最终发现可用物理内存总量的增加与已用内存的增加一致。
phys 16GB used>144508 vm>50692 user>21500 kern>26428 u+ktot>47928
vm 64MB used>24612 vm>31140 user>14956 kern>14440 u+ktot>29396
vm 256MB used>26316 vm>35260 user>14752 kern>14780 u+ktot>29532
vm 1GB used>33644 vm>35224 user>14936 kern>14772 u+ktot>29708
vm 2GB used>41592 vm>35048 user>14736 kern>15056 u+ktot>29792
vm 4GB used>57820 vm>35232 user>14780 kern>14952 u+ktot>29732
vm 8GB used>82932 vm>36912 user>15700 kern>15388 u+ktot>31088
vm 12GB used>110072 vm>35248 user>14812 kern>15624 u+ktot>30436
vm 15GB used>122012 vm>35424 user>14832 kern>15824 u+ktot>30656
Run Code Online (Sandbox Code Playgroud)
结果表明为每 1GB 内存分配了大约 8Mb。可能是内核中的内存映射......但我认为它只会随着内存的分配而不是在启动时设置而增长。
如果趋势继续下去,看看是否有人可以访问任何 bigmem 机器会很有趣吗?
在现代操作系统中,“进程使用的内存”并不是一个明确的概念。可以测量的是进程的地址空间大小(SIZE)和驻留集大小(RSS,地址空间中当前有多少页在内存中)。RSS 的一部分是共享的(内存中的大多数进程共享 glibc 的一个副本,对于各种其他共享库也是如此;运行相同可执行文件的多个进程共享它,分叉的进程共享只读数据,还可能共享一大块尚未修改的数据与父级一起读写数据)。另一方面,不考虑内核用于进程的内存,如页表、内核缓冲区和内核堆栈。在总体情况下,您必须考虑为显卡保留的内存、内核的使用以及为 DOS 和其他史前系统保留的各种“漏洞”(无论如何,这并不多)。
获得整体情况的唯一方法是内核报告的内容。将未知重叠和未知遗漏的数字相加是一个很好的算术练习,仅此而已。