GNOME Bugzilla – Bug 734761
Memory leak in implicit transition
Last modified: 2014-08-21 14:21:50 UTC
Created attachment 283343 [details] Memory Leak Profile Graph I think that there is possible memory leak in implicit animation in Clutter 1.18.4 version. To check run-time heap status, I have compiled following code and run with jemalloc profiling: #include <clutter/clutter.h> #define NUM_RECTANGLES 1000 #define RECTANGLE_WIDTH 20 #define RECTANGLE_HEIGHT 20 static ClutterActor *main_stage; static void animate_rectangle (ClutterActor *rect) { gfloat max_width; gfloat max_height; gfloat x; gfloat y; max_width = clutter_actor_get_width (main_stage) - RECTANGLE_WIDTH; max_height = clutter_actor_get_height (main_stage) - RECTANGLE_WIDTH; x = g_random_double_range (0.0, max_width); y = g_random_double_range (0.0, max_height); clutter_actor_save_easing_state (rect); clutter_actor_set_easing_mode (rect, CLUTTER_LINEAR); clutter_actor_set_easing_duration (rect, 500); clutter_actor_set_position (rect, x, y); clutter_actor_set_opacity (rect, 128 - clutter_actor_get_opacity (rect) + 16); clutter_actor_restore_easing_state (rect); } static void transition_stopped (ClutterActor *actor, gchar *name, gboolean is_finished, gpointer user_data) { animate_rectangle (actor); } int main (int argc, char **argv) { ClutterActor *stage; int i; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return 1; stage = clutter_stage_new (); clutter_actor_show (stage); clutter_stage_set_title (CLUTTER_STAGE (stage), "Implict Animation Test"); clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), TRUE); clutter_actor_set_background_color (stage, CLUTTER_COLOR_White); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); main_stage = stage; for (i = 0; i < NUM_RECTANGLES; i++) { ClutterActor *rect; rect = clutter_actor_new (); clutter_actor_add_child (stage, rect); clutter_actor_set_size (rect, 20, 20); clutter_actor_set_background_color (rect, CLUTTER_COLOR_Red); clutter_actor_set_opacity (rect, 128); animate_rectangle (rect); g_signal_connect (rect, "transition-stopped::opacity", G_CALLBACK (transition_stopped), rect); } clutter_main (); return 0; } $ gcc -g -o anitest anitest.c `pkg-config --cflags --libs clutter-1.0` $ G_DEBUG=gc-friendly \ G_SLICE=always-malloc \ LD_PRELOAD=/usr/lib/libjemalloc.so \ MALLOC_CONF="prof:true,lg_prof_interval:30" \ ./anitest After some minutes, I stopped the program with Ctrl-C and created a profile graph(which is attached to this bug) like: $ jemalloc-pprof --show_bytes --lines --svg --base=jeprof.7430.0.i0.heap anitest jeprof.7430.3.i3.heap > anitest-heap.svg I don't know if this is the problem in my code or in Clutter. But after I modify Clutter code like following, memory leak is gone. diff -uNrp clutter-1.18.4/clutter/clutter-actor.c clutter-1.18.4.new/clutter/clutter-actor.c --- clutter-1.18.4/clutter/clutter-actor.c 2014-08-07 19:41:17.000000000 +0900 +++ clutter-1.18.4.new/clutter/clutter-actor.c 2014-08-14 13:06:23.840573543 +0900 @@ -18724,6 +18724,13 @@ on_transition_stopped (ClutterTransition g_signal_emit (actor, actor_signals[TRANSITIONS_COMPLETED], 0); } + + if (clos->is_implicit || + clutter_transition_get_remove_on_complete (transition)) + { + /* we can release the reference here */ + g_object_unref (transition); + } } Any idea or suggestion?
you're correct, and the patch is correct. thanks for the thorough investigation! as a side note: the next time, make sure to attach a patch using `git-bz` or using `git format-patch`, so I can easily credit you appropriately, and get your contribution included more quickly. I'll push this to the clutter-1.18 branch as well. thanks again!