如何查看Linux对RAM的看法以确定内存碎片化情况

32
我所知道的唯一与此相关的程序是pmap,但它只打印一个进程的内存。
我想查看整个物理RAM(而不是使用pmap查看进程的视角),包括哪些进程/库以及内核占用了多少物理内存。
最好还有图形界面。
你知道是否有这样的工具吗?
我知道库引入的歧义。如果是这种情况,它可以显示一个1像素宽的线和指向该库实际位置的箭头。
我需要这个做什么?为了查看RAM碎片化。

你为什么想看那个?除非你正在开发内核代码或拥有 NUMA 系统,否则它不应该很重要。也许你把物理内存碎片和用户空间内存分配器引入的内存碎片混淆了? - thkala
4
不,我没有混淆任何东西。我的系统上有2GB的RAM,我想看看内核如何实际使用这个芯片。我只是想看看,谁知道之后可能会引发什么问题。 - Flavius
1
啊,为了学习而学习 :-) +1 - thkala
1
@thkala 这就是所谓的探索 :-) - Flavius
1个回答

39

内存碎片

当 Linux 系统运行一段时间后,内存碎片可能会增加,这严重依赖于正在运行的应用程序的性质。进程分配和释放内存越多,内存就会变得更快碎片化。而且内核可能无法及时地整理出一个请求大小所需的足够连续的内存块。如果发生这种情况,尽管有足够的空闲内存可用,应用程序可能无法分配更大的连续内存块。从 2.6 内核开始,即 RHEL4 和 SLES9,内存管理得到了极大改善,内存碎片问题已经不再是问题。

您可以使用 SysRq 魔法键查看内存碎片。只需执行以下命令:

# echo m > /proc/sysrq-trigger

这个命令将当前内存信息转储到 /var/log/messages。以下是 RHEL3 32 位系统的示例:

Jul 23 20:19:30 localhost kernel: 0*4kB 0*8kB 0*16kB 1*32kB 0*64kB 1*128kB 1*256kB 1*512kB 1*1024kB 0*2048kB 0*4096kB = 1952kB)
Jul 23 20:19:30 localhost kernel: 1395*4kB 355*8kB 209*16kB 15*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 12244kB)
Jul 23 20:19:31 localhost kernel: 1479*4kB 673*8kB 205*16kB 73*32kB 21*64kB 847*128kB 473*256kB 92*512kB 164*1024kB 64*2048kB 28*4096kB = 708564kB)

第一行显示DMA内存碎片。第二行显示低内存碎片和第三行显示高内存碎片。输出显示低内存区域的内存碎片。但是在高内存区域有许多可用的大内存块,例如28个4MB。
如果内存信息没有转储到/var/log/messages,则SysRq未启用。您可以通过将sysrq设置为1来启用SysRq:
# echo 1 > /proc/sys/kernel/sysrq

从2.6内核开始,即RHEL4和SLES9,您无需使用SysRq来转储内存信息。您只需检查/proc/buddyinfo以获取内存碎片化信息。

这是一个运行2.6内核的64位服务器的输出:

# cat /proc/buddyinfo

Node 0, zone DMA 5 4 3 4 3 2 1 0 1 1 2
Node 0, zone Normal 1046 527 128 36 17 5 26 40 13 16 94
# echo m > /proc/sysrq-trigger
# grep Normal /var/log/messages | tail -1
Jul 23 21:42:26 localhost kernel: Normal: 1046*4kB 529*8kB 129*16kB 36*32kB 17*64kB 5*128kB 26*256kB 40*512kB 13*1024kB 16*2048kB 94*4096kB = 471600kB
#

在这个例子中,我再次使用了SysRq来展示/proc/buddyinfo中每个数字所指的内容。
来源:http://www.puschitz.com/pblog/

2
一个重要的细节是:应用程序 不会分配连续的内存块 - 它们只能访问虚拟内存。只有内核需要连续的物理块 - 这就是物理 RAM 碎片可能成为问题的地方。 - thkala
2
这里有一个小测试来检查一下:char *p = malloc(256 * 1024 * 1024); 在大多数现代系统上,只要它们没有接近内存耗尽的边缘,这个测试应该会非常成功。 - thkala
2
嗯... 严格来说,你还需要一个 memset() 调用或其他方法来避免过度提交... - thkala
1
@thkala:一些用户空间请求可能最终需要连续的内存,例如AF_UNIX dgram/seqpacket发送,参见https://dev59.com/9G445IYBdhLWcg3wuceo#4822037 - ninjalj
1
@ninjalj:我们就说我很长时间没有看到这么多的“糟糕”消息了吧... - thkala
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接