2010-11-23 55 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