2012-10-27 172 views
3

我在嵌入式Linux平臺上運行Qt應用程序。該系統擁有128 MB RAM,512MB NAND,無需交換。該應用程序使用外設的自定義庫,其餘都是Qt和c/C++庫。該應用程序也使用SQLITE3。Qt應用程序因爲內存不足(OOM)而死亡

2-3小時後,機器開始運行非常慢,shell命令需要10秒左右才能響應。最終機器掛起,最後OOM殺手終止應用程序,系統開始以正常速度運行。

使用頂部命令一些系統內存的觀察之後發現,雖然應用程序運行時,系統免費記憶下降,而不斷增加。這些是下面給出的頂部的快照。該應用程序被命名爲xyz

在應用程序啓動:

Mem total:126164 anon:3308 map:8436 free:32456 
slab:60936 buf:0 cache:27528 dirty:0 write:0 
Swap total:0 free:0 
    PID VSZ VSZRW^ RSS (SHR) DIRTY (SHR) STACK COMMAND 
    776 29080 9228 8036 528 968  0 84 ./xyz -qws 
    781 3960 736 1976 1456 520  0 84 sshd: [email protected] 
    786 3676 680 1208 764 416  0 88 /usr/libexec/sftp-server 
    770 3792 568 1948 1472 464  0 84 {sshd} sshd: [email protected]/0 
    766 3792 568 956 688 252  0 84 /usr/sbin/sshd 
    388 1864 284 552 332 188  0 84 udevd --daemon 
    789 2832 272 688 584 84  0 84 top 
    774 2828 268 668 560 84  0 84 -sh 
    709 2896 268 556 464 80  0 84 /usr/sbin/inetd 
    747 2828 268 596 516 68  0 84 /sbin/getty -L ttymxc0 115200 vt100 
    777 2824 264 444 368 68  0 84 tee out.log 
    785 2824 264 484 416 68  0 84 sh -c /usr/libexec/sftp-server 
    1 2824 264 556 488 64  0 84 init 

一段時間後:

Mem total:126164 anon:3312 map:8440 free:9244 
slab:83976 buf:0 cache:27584 dirty:0 write:0 
Swap total:0 free:0 
    PID VSZ VSZRW^ RSS (SHR) DIRTY (SHR) STACK COMMAND 
    776 29080 9228 8044 528 972  0 84 ./xyz -qws 
    781 3960 736 1976 1456 520  0 84 sshd: [email protected] 
    786 3676 680 1208 764 416  0 88 /usr/libexec/sftp-server 
    770 3792 568 1948 1472 464  0 84 {sshd} sshd: [email protected]/0 
    766 3792 568 956 688 252  0 84 /usr/sbin/sshd 
    388 1864 284 552 332 188  0 84 udevd --daemon 
    789 2832 272 688 584 84  0 84 top 
    774 2828 268 668 560 84  0 84 -sh 
    709 2896 268 556 464 80  0 84 /usr/sbin/inetd 
    747 2828 268 596 516 68  0 84 /sbin/getty -L ttymxc0 115200 vt100 
    777 2824 264 444 368 68  0 84 tee out.log 
    785 2824 264 484 416 68  0 84 sh -c /usr/libexec/sftp-server 
    1 2824 264 556 488 64  0 84 init 

有趣地,雖然,我不能看到的頂部輸出的任何重大變化涉及到應用程序本身。最終,應用被殺害,之後頂部輸出:

Mem total:126164 anon:2356 map:916 free:2368 
slab:117944 buf:0 cache:1580 dirty:0 write:0 
Swap total:0 free:0 
    PID VSZ VSZRW^ RSS (SHR) DIRTY (SHR) STACK COMMAND 
    781 3960 736 708 184 520  0 84 sshd: [email protected] 
    786 3724 728 736 172 484  0 88 /usr/libexec/sftp-server 
    770 3792 568 648 188 460  0 84 {sshd} sshd: [email protected]/0 
    766 3792 568 252  0 252  0 84 /usr/sbin/sshd 
    388 1864 284 188  0 188  0 84 udevd --daemon 
    819 2832 272 676 348 84  0 84 top 
    774 2828 268 512 324 96  0 84 -sh 
    709 2896 268 80  0 80  0 84 /usr/sbin/inetd 
    747 2828 268 68  0 68  0 84 /sbin/getty -L ttymxc0 115200 vt100 
    785 2824 264 68  0 68  0 84 sh -c /usr/libexec/sftp-server 
    1 2824 264 64  0 64  0 84 init 

dmesg的顯示:

sh invoked oom-killer: gfp_mask=0xd0, order=2, oomkilladj=0 
[<c002d4c4>] (unwind_backtrace+0x0/0xd4) from [<c0073ac0>]    (oom_kill_process+0x54/0x1b8) 
[<c0073ac0>] (oom_kill_process+0x54/0x1b8) from [<c0073f14>] (__out_of_memory+0x154/0x178) 
[<c0073f14>] (__out_of_memory+0x154/0x178) from [<c0073fa0>] (out_of_memory+0x68/0x9c) 
[<c0073fa0>] (out_of_memory+0x68/0x9c) from [<c007649c>] (__alloc_pages_nodemask+0x3e0/0x4c8) 
[<c007649c>] (__alloc_pages_nodemask+0x3e0/0x4c8) from [<c0076598>] (__get_free_pages+0x14/0x4c) 
[<c0076598>] (__get_free_pages+0x14/0x4c) from [<c002f528>] (get_pgd_slow+0x14/0xdc) 
[<c002f528>] (get_pgd_slow+0x14/0xdc) from [<c0043890>] (mm_init+0x84/0xc4) 
[<c0043890>] (mm_init+0x84/0xc4) from [<c0097b94>] (bprm_mm_init+0x10/0x138) 
[<c0097b94>] (bprm_mm_init+0x10/0x138) from [<c00980a8>] (do_execve+0xf4/0x2a8) 
[<c00980a8>] (do_execve+0xf4/0x2a8) from [<c002afc4>] (sys_execve+0x38/0x5c) 
[<c002afc4>] (sys_execve+0x38/0x5c) from [<c0027d20>] (ret_fast_syscall+0x0/0x2c) 
Mem-info: 
DMA per-cpu: 
CPU 0: hi: 0, btch: 1 usd: 0 
Normal per-cpu: 
CPU 0: hi: 42, btch: 7 usd: 0 
Active_anon:424 active_file:11 inactive_anon:428 
inactive_file:3 unevictable:0 dirty:0 writeback:0 unstable:0 
free:608 slab:29498 mapped:14 pagetables:59 bounce:0 
DMA free:692kB min:268kB low:332kB high:400kB active_anon:0kB inactive_anon:0kB active_file:4kB inactive_file:0kB unevictable:0kB present:24384kB pages_scanned:0 all_unreclaimable? no 
lowmem_reserve[]: 0 103 103 
Normal free:1740kB min:1168kB low:1460kB high:1752kB active_anon:1696kB inactive_anon:1712kB active_file:40kB inactive_file:12kB unevictable:0kB present:105664kB pages_scanned:0 all_unreclaimable? no 
lowmem_reserve[]: 0 0 0 
DMA: 3*4kB 3*8kB 5*16kB 2*32kB 4*64kB 2*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 692kB 
Normal: 377*4kB 1*8kB 4*16kB 1*32kB 2*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 1740kB 
30 total pagecache pages 
0 pages in swap cache 
Swap cache stats: add 0, delete 0, find 0/0 
Free swap = 0kB 
Total swap = 0kB 
32768 pages of RAM 
687 free pages 
1306 reserved pages 
29498 slab pages 
59 pages shared 
0 pages swap cached 
Out of memory: kill process 774 (sh) score 339 or a child 
Killed process 776 (xyz) 

所以,很明顯是有內存泄漏,那一定是我的應用程序,因爲我的應用程序被殺害。但我沒有做任何程序中的任何malloc。我很注意限制變量的範圍,以便在使用它們之後將其釋放。所以我完全喪失了爲什麼板坯增加在頂部輸出。我試過http://valgrind.org/docs/manual/faq.html#faq.reports但沒有工作。

當前嘗試在桌面上使用Valgrind(因爲我已閱讀它只適用於arm-cortex)來檢查我的業務邏輯。

Addittional信息:

[email protected] ~/Application/app$ uname -a 
Linux freescale 2.6.31-207-g7286c01 #2053 Fri Jun 22 10:29:11 IST 2012 armv5tejl GNU/Linux 
Compiler : arm-none-linux-gnueabi-4.1.2 glibc2.5 
cpp libs : libstdc++.so.6.0.8 
Qt : 4.7.3 libs 

任何指針將不勝感激......

+2

那麼你沒有做任何malloc,但你正在使用一些庫,可能正在做mallocs。所以也許你沒有正確使用這些庫,那是什麼導致你的內存泄漏。可能是 – john

+0

,但這正是我想要找出的。 Valgrind正在報告所有Qt庫中的泄漏......不知道爲什麼。但我也正在檢查圖書館。 – aditya

+0

有關Qt和內存泄漏的SO有很多問題,Valgrind經常報告由於Qt的隱式共享和插件系統導致的誤報。 – cmannett85

回答

1

如果你有一些數據結構分配,檢查將兒童和等的正確性..我有類似的bug在我的代碼中。此外,如果您對數據庫進行大型和大型查詢,它可能會使用更多的RAM內存。嘗試找到一些內存泄漏檢測器來查找是否有泄漏。

+0

這是意圖被評論,而不是回答! –

+0

實際上,正如我上面提到的那樣,我嘗試使用Valgrind,它會一直在Qt庫中報告泄漏。謝謝回覆。 – aditya

3

我不認爲這個問題是直接在你的代碼中。 原因很明顯:您的應用程序空間不會增加(RSS和VSW都不會增加)。

但是,您確實看到了增加的厚片數量。你不能在應用程序中使用或增加平板的數量 - 這是一個內核專用的東西。

從我頭頂的樓板尺寸增加一些顯而易見的原因:

  • 你永遠不會真正關閉網絡套接字
  • 你看了很多文件,但從來沒有關閉它們
  • 您使用許多的ioctl

我會運行strace並查看它的輸出一段時間。 strace截取與內核的交互。如果你有內存問題,我希望重複調用brk()。如果你有其他問題,你會看到重複的電話打開沒有關閉。

+0

好吧,我可以放心地排除_network sockets_,因爲我沒有使用它們(我很確定,我甚至關閉了GPRS)。我正在使用文件,但總共有6個,包括數據庫,並且我也關注它們。但是肯定會有很大的_ioctl_活動,因爲外設(strace證實了它)。儘管沒有很多_open_電話。順便說一句,是不是_slab_影響,如果malloc從應用程序調用? – aditya

+0

@aditya:不,slab是僅在內核中使用的內存池。 malloc()被glibc轉換爲brk()調用 - 用於較大的區域。由glibc創建的區域隨後以應用程序所需的任何小塊分發。 –

相關問題