1

我有一个在 Solaris (SunOS m1001 5.10 sun4v sparc) 上运行的进程,并且正在监视使用的总虚拟内存。

定期运行 ps 表明 VSZ 随着时间的推移呈线性增长,跃迁 80kbytes,并且它一直在增长,直到达到 4GB 限制,此时它的地址空间不足,事情开始分崩离析。

while true; do ps -ef -o pid,vsz,rss|grep 27435 ; sleep 5; done > ps.txt

我怀疑内存泄漏,并决定使用 pmap 进一步调查。但是 pmap 显示 VSZ 根本没有增长,而是保持稳定。此外,所有文件映射、共享内存映射和堆都保持相同的大小。

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 增长的原因的最佳方法是什么。

4

2 回答 2

1

我注意到这个问题仍然悬而未决,想补充一下这个故事是如何结束的。

经过更多的挖掘后,我联系了 Solari 的客户支持,并向他们发送了重现问题的方法。他们确认内核中存在导致此行为的错误。

不幸的是,我无法确认他们是否推出了补丁,因为我离开了我当时工作的公司。

谢谢,杰夫

于 2018-11-21T16:42:49.470 回答
0

如果您使用 运行您的可疑进程LD_PRELOAD=libumem.so,那么在“一切都崩溃”的时候,您可以对其进行 gcore - 然后使用 umem dcmd 在其上运行 mdb,例如::findleaks -dv.

如果您查看 pmap(1) 输出中列出的所有映射,而不仅仅是进程的总数,您将更好地了解在哪里查看。我首先要查找的是堆、匿名和堆栈段。

于 2016-02-29T03:58:58.610 回答