Solaris:pmap 报告的虚拟内存大小与 ps 不同
Solaris : pmap reports a different virtual memory size than ps
我在 Solaris (SunOS m1001 5.10 sun4v sparc) 上有一个进程 运行,并且正在监视使用的总虚拟内存。
周期性地 运行 ps 表明 VSZ 随着时间的推移呈线性增长,jumps 为 80kbytes 并且它保持 ps 增长直到达到 4GB 限制在这一点上它超出了地址 space 并且事情开始分崩离析。
while true; do ps -ef -o pid,vsz,rss|grep 27435 ; sleep 5; done > ps.txt
我怀疑内存泄漏并决定使用 pmap 进一步调查。但是 pmap 显示 VSZ 根本没有增长,而是保持稳定。所有文件 maps、共享内存 maps 和堆都保持相同的大小。
while true; do pmap -x 27435 |grep total; sleep 5; done > pmap.txt
我的第一个问题是:为什么 ps 和 pmap 为同一进程生成不同的 VSZ?
我可以想象堆大小的计算方式不同(例如,堆使用率与最高堆指针),因此开始考虑堆碎片化的方向。然后,我使用 libumem 和 mdb 在不同时间生成有关分配内存的详细报告,并注意到分配内存绝对没有差异。
mdb 27435 < $umem_cmds
::walk thread |::findstack !tee>>umemc-findstack.log
::umalog !tee>>umem-umalog.log
::umastat !tee>>umem-umastat.log
::umausers !tee>umem-umausers.log
::umem_cache !tee>>umem-umem_cache.log
::umem_log !tee>>umem-umem_log.log
::umem_status !tee>>umem-umem_status.log
::umem_malloc_dist !tee>>umem-umem_malloc_dist.log
::umem_malloc_info !tee>>umem-umem_malloc_info.log
::umem_verify !tee>>umem-umem_verify.log
::findleaks -dv !tee>>umem-findleaks.log
::vmem !tee>>umem-vmem.log
*umem_oversize_arena::walk vmem_alloc | ::vmem_seg -v !tee>umem- oversize.log
*umem_default_arena::walk vmem_alloc | ::vmem_seg -v !tee>umem-default.log
所以我的第二个问题是:找出导致 ps.
报告的 VSZ 不断增长的原因的最佳方法是什么
如果您 运行 您的可疑进程使用 LD_PRELOAD=libumem.so
,那么在 "it all falls apart" 的位置您可以对其进行 gcore - 然后 运行 mdb 使用 umem dcmd,例如 ::findleaks -dv
.
如果您查看 pmap(1) 输出中列出的所有映射,而不仅仅是进程的总计,您将会更好地了解要查看的位置。我首先要查找的是堆、匿名和堆栈段。
我注意到这个问题仍然悬而未决,想补充一下这个故事的结局。
经过更多的挖掘,我联系了 Solari 的客户支持,并向他们发送了重现该问题的方法。
他们确认内核中存在导致此行为的错误。
不幸的是,我无法确认他们推出了补丁,因为我离开了我当时工作的公司。
谢谢,杰夫
我在 Solaris (SunOS m1001 5.10 sun4v sparc) 上有一个进程 运行,并且正在监视使用的总虚拟内存。
周期性地 运行 ps 表明 VSZ 随着时间的推移呈线性增长,jumps 为 80kbytes 并且它保持 ps 增长直到达到 4GB 限制在这一点上它超出了地址 space 并且事情开始分崩离析。
while true; do ps -ef -o pid,vsz,rss|grep 27435 ; sleep 5; done > ps.txt
我怀疑内存泄漏并决定使用 pmap 进一步调查。但是 pmap 显示 VSZ 根本没有增长,而是保持稳定。所有文件 maps、共享内存 maps 和堆都保持相同的大小。
while true; do pmap -x 27435 |grep total; sleep 5; done > pmap.txt
我的第一个问题是:为什么 ps 和 pmap 为同一进程生成不同的 VSZ?
我可以想象堆大小的计算方式不同(例如,堆使用率与最高堆指针),因此开始考虑堆碎片化的方向。然后,我使用 libumem 和 mdb 在不同时间生成有关分配内存的详细报告,并注意到分配内存绝对没有差异。
mdb 27435 < $umem_cmds
::walk thread |::findstack !tee>>umemc-findstack.log
::umalog !tee>>umem-umalog.log
::umastat !tee>>umem-umastat.log
::umausers !tee>umem-umausers.log
::umem_cache !tee>>umem-umem_cache.log
::umem_log !tee>>umem-umem_log.log
::umem_status !tee>>umem-umem_status.log
::umem_malloc_dist !tee>>umem-umem_malloc_dist.log
::umem_malloc_info !tee>>umem-umem_malloc_info.log
::umem_verify !tee>>umem-umem_verify.log
::findleaks -dv !tee>>umem-findleaks.log
::vmem !tee>>umem-vmem.log
*umem_oversize_arena::walk vmem_alloc | ::vmem_seg -v !tee>umem- oversize.log
*umem_default_arena::walk vmem_alloc | ::vmem_seg -v !tee>umem-default.log
所以我的第二个问题是:找出导致 ps.
报告的 VSZ 不断增长的原因的最佳方法是什么如果您 运行 您的可疑进程使用 LD_PRELOAD=libumem.so
,那么在 "it all falls apart" 的位置您可以对其进行 gcore - 然后 运行 mdb 使用 umem dcmd,例如 ::findleaks -dv
.
如果您查看 pmap(1) 输出中列出的所有映射,而不仅仅是进程的总计,您将会更好地了解要查看的位置。我首先要查找的是堆、匿名和堆栈段。
我注意到这个问题仍然悬而未决,想补充一下这个故事的结局。
经过更多的挖掘,我联系了 Solari 的客户支持,并向他们发送了重现该问题的方法。 他们确认内核中存在导致此行为的错误。
不幸的是,我无法确认他们推出了补丁,因为我离开了我当时工作的公司。
谢谢,杰夫