您的位置:首页 > 其它

一次GTK程序内存泄露的解决过程发现的两个内存泄露的问题

2009-09-03 16:23 806 查看
集成测试的时候发现一个程序在持续的运行过程中有缓慢的内存增长。用ValGrind来查并没有太多的发现。询问开发人员的时候,他说GTK的内存好象都有一些泄露,网上有文曰

If GtkFoo
isn't a toplevel window, then

foo = gtk_foo_new ();

gtk_widget_destroy (foo);


is a memory leak。

这个我是不相信的,于是有了两个内存泄露的问题需要解释。

1、我们的程序为什么内存泄露?在放弃了工具帮忙后,逐段代码注释,注释后并细心观察内存半个小时后记录内存起伏情况。最后发现我们的代码确实有问题。

GList *list_child;

......

list_child=gtk_container_get_children (GTK_CONTAINER (button));

fixed=GTK_WIDGET(list_child->data);

list_child=gtk_container_get_children (GTK_CONTAINER (fixed));

image=GTK_WIDGET(list_child->data);

shadow=button_array_item->shadow;

我们想当然认为list_child不用释放,是容器内部管理的GList列表,实际上,文档明确说返回值是一个newly-allocated的list :

gtk_container_get_children ()

GList

*              gtk_container_get_children          (GtkContainer

*container);


Returns the container's non-internal children. See
gtk_container_forall()


for details on what constitutes an "internal" child.

container


:

a GtkContainer

Returns

:

a newly-allocated list of the container's non-internal children.
2、同事说的例子为什么有内存泄露?找了文章看到下面的解释

1.5.
Why does my program leak memory, if I destroy a widget immediately
after creating it ?

If GtkFoo
isn't a toplevel window, then

foo = gtk_foo_new ();

gtk_widget_destroy (foo);


is a memory leak, because no one assumed the initial floating
reference. If you are using a widget and you aren't immediately
packing it into a container, then you probably want standard
reference counting, not floating reference counting.

To to get this, you must acquire a reference to the widget and drop the floating
reference (“ref and sink
” in GTK+ parlance) after creating it:

foo = gtk_foo_new ();

g_object_ref (foo);

gtk_object_sink (GTK_OBJECT (foo));


When you want to get rid of the widget, you must call gtk_widget_destroy()
to break any external connections to the widget before dropping your
reference:

gtk_widget_destroy (foo);

g_object_unref (foo);


When you immediately add a widget to a container, it takes care of
assuming the initial floating reference and you don't have to worry
about reference counting at all ... just call gtk_widget_destroy()
to get rid of the widget.

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐