【问题标题】:Linux Process shows sudden Memory JumpLinux 进程显示突然的内存跳转
【发布时间】:2013-07-26 07:18:13
【问题描述】:

我有一个多线程的 linux 服务器(64 位),它应该可以运行和处理几天的请求。但是一段时间以来,我看到进程的内存利用率突然上升。有时这会在一段时间后下降,但有时我的进程在达到阈值限制后会崩溃。

我使用 smapspmap 查找映射,发现堆大小为 390 MB,而当时的总内存利用率为 4.5GB。

我可以在 pmaps 输出中看到很多匿名内存段,所以我运行了 strace,发现在内存跳转时我的进程正在调用大小为 134MB 的 mmap:

29045 19:52:45 mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x2aabf8000000
29045 19:53:12 mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x2aac00000000
29045 19:53:21 mmap(0x2aac04000000, 67108864, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x2aac04000000
29045 19:53:28 mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x2aac08000000

我为 ma​​lloc 编写了包装器,发现我的应用程序完成的最大内存分配是一个 30MB 分配和一个 20MB 分配在跳转时。并且这块内存被释放了。

我需要知道为什么我的进程会调用这些大型 mmap?

附加信息:

我在 mmap 上破解,发现下面的 BT:

#0  0x00000032af6d0940 in mmap64 () from /lib64/libc.so.6
#1  0x00000032af66f9cf in new_heap () from /lib64/libc.so.6
#2  0x00000032af673515 in _int_malloc () from /lib64/libc.so.6
#3  0x00000032af674cde in malloc () from /lib64/libc.so.6

malloc 调用了 5060 字节,但 mmap 调用了大小 134217728。为什么 malloc 调用 new_heap()?

【问题讨论】:

  • 可能是 malloc() 为“小”分配创建了一个新堆。根据 malloc 实现,您可能会为不同的分配大小获得不同的堆(例如,一个用于 4096 到 8092 字节之间的 malloc() 调用,另一个用于 10 到 20MB 之间的分配......)。你能检查其他 mmap() 调用的回溯并检查它们的分配大小吗?
  • 另外,如果你做了很多小分配,你的堆可能会变得碎片化,导致内存浪费?你能检查一下你正在做多少分配小分配的 malloc() 和 free() 调用吗?另外,请参阅stackoverflow.com/questions/3770457/… 了解概览。

标签: linux malloc mmap


【解决方案1】:

您可以尝试将 GDB 附加到进程并在 mmap() 上设置条件断点。这将为您提供大量分配的回溯。

【讨论】:

  • 好的,我会试试这个,但我的代码不会在任何地方直接调用 mmap。令人惊讶的是,我的堆并没有那么大,而且 malloc 没有被大尺寸调用,所以我的内存还去哪里了?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 2014-02-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多