一次GTK程序内存泄露的解决过程发现的两个内存泄露的问题
2009-09-03 16:23
806 查看
集成测试的时候发现一个程序在持续的运行过程中有缓慢的内存增长。用ValGrind来查并没有太多的发现。询问开发人员的时候,他说GTK的内存好象都有一些泄露,网上有文曰
If GtkFoo
isn't a toplevel window, then
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 :
Returns the container's non-internal children. See
for details on what constitutes an "internal" child.
2、同事说的例子为什么有内存泄露?找了文章看到下面的解释
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. |
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. |
相关文章推荐
- SQLSERVER 占了500多M内存,原来的程序无法一次查询出50多W数据了,记录下这个问题的解决过程。
- 如何解决Qt 4GUI程序中动态创建内存的泄露问题
- 一次性能测试过程中发现的两个问题点
- 一次内存泄漏问题的发现与解决过程
- MFC解决程序退出时死锁和内存或资源泄露的问题
- 解决程序退出时死锁和内存或资源泄露的问题
- ftp 21端口被占用解决办法 解决过程中发现两个问题
- 多线程 DLL 回调函数问题,当应用程序退出时,有些操作并未完成,造成程序内存泄露,如何解决呢
- C++编译过程中"没有找到MFC80UD.DLL,因此这个程序未能启动.重新安装应用程序可能会修复此问题"? 的彻底解决
- 在eclipse中JAVA从打包成jar程序到双击运行的整个过程(没有主清单属性问题的解决)
- 测试之路——记一次解决问题的过程
- RxLifecycle使用 解决Rxjava编程的内存泄露问题
- Android sdk manger安装过程中,发现无法改名的问题,解决后,点击 manger.EXE 无法更新剩下的包
- C++编译过程中"没有找到MFC80UD.DLL,因此这个程序未能启动.重新安装应用程序可能会修复此问题"? 的彻底解决
- 解决存储过程执行快,但程序调用则执行慢的问题
- 应用 Valgrind 发现 Linux 程序的内存问题
- 一次对HBase协处理器的内存耗尽问题的GC分析和解决
- Rxlifecycle使用详解,解决RxJava内存泄露问题
- ACE的ACE_Logging_Strategy类中的一个多线程安全问题的发现及解决过程