昨天解決了一個(gè)隱蔽的內(nèi)存泄漏問題,原因是pthread_create后的僵死線程沒有釋放導(dǎo)致的內(nèi)存持續(xù)增長(zhǎng)。
現(xiàn)象是這樣的:短時(shí)間內(nèi)程序運(yùn)行正常,但跑了12小時(shí)左右,用top查看其內(nèi)存占用居然高達(dá)2G,于是馬上意識(shí)到有內(nèi)存泄漏。
最先想到的是malloc/free、new/delete沒有配對(duì),申請(qǐng)的內(nèi)存沒有釋放。于是寫了個(gè)跟蹤malloc/free調(diào)用的模塊,不過檢查中并沒有找到未釋放的內(nèi)存。之后懷疑是不是 free then malloc 導(dǎo)致的內(nèi)存管理錯(cuò)誤(事實(shí)證明雖然free后不是立即回收內(nèi)存,但是接連調(diào)用free & malloc并不會(huì)影響操作系統(tǒng)的內(nèi)存管理),不過寫了個(gè)小程序發(fā)現(xiàn)并不是這么回事。
陷入窘境了,只好用最小系統(tǒng)法把功能部分和內(nèi)存分配都給屏蔽掉,這時(shí)發(fā)現(xiàn)內(nèi)存泄漏依然存在!仔細(xì)看top的輸出,幾乎是每次創(chuàng)建線程時(shí)內(nèi)存就往上漲一點(diǎn),只是增長(zhǎng)速度不是很快,看來是線程的問題了。仔細(xì)分析發(fā)現(xiàn),之前圖簡(jiǎn)單 pthread_create (&thread, NULL, &thread_function, NULL); 就這么寫了,參數(shù)2沒有設(shè)置線程結(jié)束后自動(dòng)detach,并且沒有使用pthread_join或pthread_detach釋放執(zhí)行結(jié)束后線程的空間!
Linux man page 里有已經(jīng)說明了這個(gè)問題:
When a joinable thread terminates, its memory resources (thread descriptor and stack) are not deallocated until another thread performs pthread_join on it. Therefore, pthread_join must be called once for each joinable thread created to avoid memory leaks.
也就說線程執(zhí)行完后如果不join的話,線程的資源會(huì)一直得不到釋放而導(dǎo)致內(nèi)存泄漏!一時(shí)的圖快后患無窮啊。
解決辦法:
代碼 1 // 最簡(jiǎn)單的辦法,在線程執(zhí)行結(jié)束后調(diào)用pthread_detach讓他自己釋放
2 pthread_detach(pthread_self());
3
4
5 // 或者創(chuàng)建線程前設(shè)置 PTHREAD_CREATE_DETACHED 屬性
6 pthread_attr_t attr;
7 pthread_t thread;
8 pthread_attr_init (&attr);
9 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
10 pthread_create (&thread, &attr, &thread_function, NULL);
11 pthread_attr_destroy (&attr);
第2行的那種方法最簡(jiǎn)單,在線程函數(shù)尾部加上這句話就可以將線程所占用的資源給釋放掉;或者像 5-11 所示的方法設(shè)置detach屬性,這樣也會(huì)在線程return/pthread_exit后釋放內(nèi)存。
其實(shí)仔細(xì)想想,valgrind檢查時(shí)已經(jīng)提示了pthread_create沒有釋放的問題,只是之前沒引起注意。其實(shí)這樣的問題也只有在長(zhǎng)時(shí)間運(yùn)行時(shí),慢慢積累這一點(diǎn)點(diǎn)的內(nèi)存才會(huì)暴露出來,看來valgrind的提示也不能置之不理啊。
from:
http://www.cnblogs.com/bits/archive/2009/12/04/no_join_or_detach_memory_leak.html
posted on 2010-01-14 16:40
chatler 閱讀(3105)
評(píng)論(2) 編輯 收藏 引用 所屬分類:
Linux_Coding