如何检测内存泄漏?

我现在的ubuntu系统似乎有更大的内存泄漏

在报告奇怪的Eclipse内存错误( https://askubuntu.com/questions/148998/eclipse-constant-different-out-of-memory-errors )之后,我今天在我的控制台中开始出现“内存不足”错误消息 – 而做一些简单的任务,比如输入sudo -s – 甚至是 – free -m

重复输入’free -m’向我展示了我的RAM如何快速从700M上升到900M,在几秒钟内增长到2000M(在使用echo 3 > /proc/sys/vm/drop_caches释放内存之后)

Eclipse不是原因,我完全杀死了这个过程,而ram仍然在上升。 有没有办法检测泄漏的来源? 我甚至不能更新我的系统,因为apt-get update失败(可能是因为内存不足)

使用Ubuntu 11.10

memprof是一个用于分析内存使用情况和查找内存泄漏的工具。 它可以生成一个配置文件,程序中的每个函数分配了多少内存。 此外,它还可以扫描内存并查找已分配但不再在任何位置引用的块。

memprof通过预加载库来覆盖C库的内存分配函数,并且不需要您重新编译程序。

memprof

资料来源:Ubuntu手册

drop_cache技巧不会释放内存,它会重置缓存。 如果要确定哪些进程使用的内存较多,则使用ps命令。

例如,监视驻留内存用户的前15名列表。

 $ watch "ps --sort -rss -eo pid,pmem,rss,vsz,comm | head -16" PID %MEM RSS VSZ COMMAND 2590 13.4 136892 825000 firefox 1743 10.7 109020 300780 Xorg 2067 8.5 86764 1118140 unity-2d-shell 3307 4.1 42560 627780 unity-2d-spread 2068 2.9 29904 617644 unity-2d-panel 2092 2.5 25524 1291204 nautilus 2457 1.9 20292 530276 gnome-terminal 2351 1.9 20016 821488 unity-scope-vid 2161 1.9 19476 531968 unity-panel-ser 2034 1.7 18256 759716 gnome-settings- 2074 1.5 16176 518016 nm-applet 2273 1.5 15452 580416 unity-lens-vide 2051 1.4 15112 524260 metacity 2395 1.2 12836 407336 update-notifi 

您也可以检查共享内存预留,但您只知道谁是段的所有者。

Pmap分配:

 $ ls -l /run/shm total 272 -r-------- 1 ed ed 67108904 Nov 29 18:17 pulse-shm-1884617860 -r-------- 1 lightdm lightdm 67108904 Nov 29 18:11 pulse-shm-2352897759 -r-------- 1 ed ed 67108904 Nov 29 18:12 pulse-shm-3444873503 -r-------- 1 ed ed 67108904 Nov 29 18:12 pulse-shm-3485341848 -r-------- 1 lightdm lightdm 67108904 Nov 29 18:11 pulse-shm-535843976 -r-------- 1 ed ed 67108904 Nov 29 19:12 pulse-shm-789046959 -r-------- 1 ed ed 67108904 Nov 29 18:38 pulse-shm-863909656 $ df /run/shm Filesystem 1K-blocks Used Available Use% Mounted on none 509332 272 509060 1% /run/shm 

请注意,保留的分配远远高于实际分配的页面(df’使用’)

系统V分配:

 $ ipcs -m ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 294912 ed 700 122880 2 dest 0x00000000 327681 ed 700 4823040 2 dest 0x00000000 491522 ed 600 393216 2 dest 0x00000000 589827 ed 700 4578120 2 dest 0x00000000 425988 ed 700 27852 2 dest 0x00000000 458757 ed 600 393216 2 dest 

编辑 :需要将--sort -rss传递给ps以获取具有最大内存使用量的进程,否则进程列表--sort -rss数字排序,并为进程提供最少的内存使用量。

这几乎可以保证找到泄漏内存的步骤:

  1. 找出导致内存泄漏的进程的PID。

     ps -aux 
  2. 捕获/proc/PID/smaps并保存到某些文件中,如BeforeMemInc.txt

  3. 等到记忆力增加。
  4. 再次捕获/proc/PID/smaps并将其保存为afterMemInc.txt
  5. 找到第一个smaps和第二个smaps之间的区别,例如

    diff -u beforeMemInc.txt afterMemInc.txt

  6. 记下内存增加的地址范围,例如:

      beforeMemInc.txt afterMemInc.txt --------------------------------------------------- 2b3289290000-2b3289343000 2b3289290000-2b3289343000 #ADDRESS Shared_Clean: 0 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Clean: 0 kB Private_Dirty: 28 kB Private_Dirty: 36 kB Referenced: 28 kB Referenced: 36 kB Anonymous: 28 kB Anonymous: 36 kB #INCREASE MEM AnonHugePages: 0 kB AnonHugePages: 0 kB Swap: 0 kB Swap: 0 kB KernelPageSize: 4 kB KernelPageSize: 4 kB MMUPageSize: 4 kB MMUPageSize: 4 kB Locked: 0 kB Locked: 0 kB VmFlags: rd wr mr mw me ac VmFlags: rd wr mr mw me ac 
  7. 使用GDB在运行进程中转储内存或使用gcore -o process获取coredump

  8. 我在运行进程中使用gdb将内存转储到某个文件。

     gdb -p PID dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000 
  9. 现在,使用strings命令或hexdump -C来打印dump_outputfile.dump

     strings outputfile.dump 
  10. 您可以获得可读forms,您可以在源代码中找到这些字符串。

  11. 分析您的来源以找到泄漏。

我有一台旧机器,我使用它不断吐出内存泄漏消息:

 root@:~# free -m total used free shared buffers cached Mem: 1898 1523 374 131 32 588 -/+ buffers/cache: 902 995 Swap: 1942 480 1462 

我的剧本:

 sync; sudo echo 3 > /proc/sys/vm/drop_caches 

将其命名为cache.sh

 root@~# ./cache.sh root@~# free -m total used free shared buffers cached Mem: 1898 1106 791 126 1 207 -/+ buffers/cache: 897 1000 Swap: 1942 480 1462 

你可以看到我低至374 MB,运行sync; sudo echo 3 > /proc/sys/vm/drop_caches sync; sudo echo 3 > /proc/sys/vm/drop_caches并获得了417 MB的回报。 人们可以每5分钟运行一次,或者只是打开一个终端并在看到性能下降时运行它。 是的,我需要为机器添加内存……

memstat也是一个很好的工具,它将显示每个块使用的内存量以及加载的库使用的内存量。 不是最好的工具,但值得用来收集细节和统计数据。

memstat -w -p pid是一个很好用的命令。

我有一个类似的问题,但有一个非常奇怪的解决方案。

由于某些未知的原因,我的笔记本电脑上安装了一个邮件服务器并且正在运行。我不知道为什么会这样…但是我关闭了它的服务,结果certificate我的笔记本电脑上的软件是在ddos攻击下。之后一切正常。