如何检测内存泄漏?


16

我当前的ubuntu系统上似乎有更大的内存泄漏

报告了奇怪的Eclipse内存错误(/ubuntu/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


我很高兴我没有疯。自升级到13.10以来,我遇到了同样的问题,但我记得在11.10中遇到过。问题是:您正在使用CrashPlan吗?我似乎已经缩小到那个范围,我只是不知道如何解决它。我已经尝试了内存调整,但是它不起作用。我希望它能为您提供一些线索
半新手

强制内核放弃缓存没有任何意义。一旦需要更多的物理内存,它们将被刷新并以任何方式回收它们的空间。强制刷新它们很可能甚至损害整体性能,因为需要从慢得多的辅助存储中检索未缓存的对象。释放主内存绝不是一件好事。这可能是缓存管理不佳或使用率很低的迹象。
David Foerster,2014年

Answers:


9

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

memprof的工作方式是预加载库以覆盖C库的内存分配功能,并且不需要您重新编译程序。

Memprof

资料来源:Ubuntu手册


11

首先,请确保有一个具有足够可用空间的临时文件夹。以下命令创建的转储大小可能为几个GB。

您可以使用以下命令创建新的tmp文件夹。您可能需要更改/tmp为具有足够空间的其他文件系统

TMPDIR=$(mktemp -d -t -p /tmp)

查找内存泄漏的步骤

  1. 找出导致内存泄漏的进程的PID(也可以使用例如htop可用的PID )并将其存储在名为pid

    ps -aux
    
  2. 鉴于PID在变量中可用pid,您可以使用捕获内存消耗/proc/$pid/smaps并将其保存到类似的文件中beforeMemInc.txt

    cat /proc/$pid/smaps > $TMPDIR/beforeMemInc.txt
    
  3. 等待一段时间,以增加内存消耗。
  4. /proc/$pid/smaps再次捕获并将其另存为afterMemInc.txt

    cat /proc/$pid/smaps > $TMPDIR/afterMemInc.txt
    
  5. 找到first smaps和2nd 之间的差异smaps,例如

    diff -u $TMPDIR/beforeMemInc.txt $TMPDIR/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在正在运行的进程上转储内存或使用以下命令获取coredump

    gcore -o $TMPDIR/process $PID
    
  8. 我在运行的进程上使用gdb将内存转储到某些文件。

    cd $TMPDIR
    gdb -p $pid
    dump memory memory.dump 0x2b3289290000 0x2b3289343000
    
  9. 现在,使用strings命令或hexdump -C打印memory.dump

    strings memory.dump
    

    由此,您将获得可读的信息,有助于您在源代码中找到这些字符串。

  10. 分析您的来源以查找泄漏。

我在Docker容器中,cat /proc/2882/smaps > /tmp/before.txt在步骤2上运行时出现“权限被拒绝”错误。我做错了什么?
Devy

8

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 -rssps获取具有最大内存使用量的进程,否则,进程列表将按递增的顺序进行排序,并以最低的内存使用率给出进程。


5

我有一台使用较旧的计算机,不断发出内存泄漏消息:

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又获得了417 MB的内存。cron它可以每5分钟运行一次,也可以打开终端并在性能降低时运行它。是的,我需要在机器上添加内存...


格式化似乎是一个问题,不确定如何解决
Warpig

1
使用帖子下方的编辑链接。在文本区域上方有一个格式化工具栏和一个橙色问号,可链接到Markdown格式化帮助
David Foerster,2014年

请看一下我最近对这个问题的评论。我坚信通过刷新和删除缓存来释放主内存的想法是错误的,我知道我并不孤单。
David Foerster,2014年

非常感谢,大卫...我完全同意刷新/删除缓存是误导的...但是挂起了某些东西,使机器冻结/锁定了...对此一无所知,认为这是一个Firefox问题。 ..
Warpig 2014年

3

memstat还是一个很好的工具,它将显示每个块使用的内存量以及已加载的库使用多少内存。不是最好的工具,但是值得用来收集详细信息和统计信息。

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


1
链接已断开,我认为很好
vladkras 16-10-13

1

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.