2010-11-23 49 views
22

我正在開發一個使用一些glib數據結構(GHashTable,GSList等)的庫。我一直在使用valgrind經常檢查我的代碼是否存在內存泄漏。 valgrind指出的大部分問題都很容易解決,但有一些我無法弄清楚。當使用glib數據類型時,Valgrind報告內存'可能丟失'

所有這些被報告爲'可能丟失'。

在Valgrind的堆棧跟蹤的頂部,我總是發現同樣的4個庫:

==29997== 1,512 bytes in 3 blocks are possibly lost in loss record 24 of 25 
==29997== at 0x4004B11: memalign (vg_replace_malloc.c:532) 
==29997== by 0x4004B6B: posix_memalign (vg_replace_malloc.c:660) 
==29997== by 0x5E9AC4: ??? (in /lib/libglib-2.0.so.0.1200.3) 
==29997== by 0x5EA4FE: g_slice_alloc (in /lib/libglib-2.0.so.0.1200.3) 

在調用棧中再往下,總有一個油嘴函數的調用,如g_key_file_new(), g_slist_prepend(),g_strsplit(),g_key_file_load_from_file(),g_file_get_contents()。

我的問題是:

  • 有沒有人碰到,發現這個辦法解決它?

  • 或者這是我可以忽略的東西嗎?是否由於glib使用內存池,如建議here

我使用

  • 的valgrind-3.5.0
  • 巧舌如簧-2.12.3
  • 海合會(GCC)4.1.2 20080704(紅帽4.1.2-48)
  • CentOS版本5.5(最終版)

回答

32

GLib的具有迷惑Valgrind的幾個特點。

一個是內存池(g_slice在較新的glib中,「mem塊」在舊版本中)。這些是專門用於小對象(如列表節點)的分配器。你可以用這個來禁用片分配器: G_SLICE=always-malloc valgrind myprogram

第二個問題是,有時候GLib會避免初始化新內存或在釋放的片/塊中保留死指針。 G_DEBUG=gc-friendly valgrind myprogram

所以說起來當然是:你可以解決這個 G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind myprogram

的第三個問題是,GLib的具有隻是永遠不會被釋放,但考慮長期方案,狀態全局變量。例如註冊的GType從不卸載,還有一些其他的。這不是可以解決的,但valgrind應該將這些全局分配顯示爲可達,而不是丟失。

+0

使用G_SLICE = always-malloc運行程序顯示沒有丟失內存,證實了我懷疑所有(可能)內存丟失是由於內存池而發生的。感謝Havoc P的明確答案。 – ttreitlinger 2010-11-24 09:02:47

0

glib-2.12已經很老了。例如

嘗試獲取glib-2.24,編譯並安裝它(例如--prefix =/usr/local/glib-2.24),然後使用它編譯您的應用程序。

如果你仍然有這個問題,嘗試再次讀取該油嘴手動:)

+0

不幸的是我被這個版本的glib卡住了,因爲我正在開發的軟件將運行在託管服務器上,2.12是默認版本 – ttreitlinger 2010-11-23 10:36:19