After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 614725 - Call JS_MaybeGC when idle
Call JS_MaybeGC when idle
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
Depends on:
Blocks:
 
 
Reported: 2010-04-03 10:57 UTC by drago01
Modified: 2010-05-21 21:49 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
shell-global: Add shell_global_maybe_gc (1.68 KB, patch)
2010-04-03 10:57 UTC, drago01
committed Details | Review
Call global.maybe_gc when idle (1.22 KB, patch)
2010-04-03 10:58 UTC, drago01
none Details | Review
Call global.maybe_gc when idle (1.29 KB, patch)
2010-04-03 11:44 UTC, drago01
reviewed Details | Review
Call shell_global_maybe_gc() when no work is being done (1.83 KB, patch)
2010-05-21 12:29 UTC, drago01
needs-work Details | Review
Call shell_global_maybe_gc() when no work is being done (2.54 KB, patch)
2010-05-21 20:18 UTC, drago01
needs-work Details | Review
Call shell_global_maybe_gc() when no work is being done (1.49 KB, patch)
2010-05-21 21:30 UTC, drago01
committed Details | Review

Description drago01 2010-04-03 10:57:12 UTC
This makes sure that we free up memory and that we do that while no other works is being done.
Comment 1 drago01 2010-04-03 10:57:37 UTC
Created attachment 157800 [details] [review]
shell-global: Add shell_global_maybe_gc

Add a method to call JS_MaybeGC, see
https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_MaybeGC
Comment 2 drago01 2010-04-03 10:58:15 UTC
Created attachment 157801 [details] [review]
Call global.maybe_gc when idle

Call shell_global_maybe_gc when idle to free up memory and improve performance
by preventing the GC to kick in at less convenient times.

See: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_MaybeGC
Comment 3 drago01 2010-04-03 11:44:11 UTC
Created attachment 157804 [details] [review]
Call global.maybe_gc when idle

Call shell_global_maybe_gc when idle to free up memory and improve performance
by preventing the GC to kick in at less convenient times.

See: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_MaybeGC
Comment 4 Owen Taylor 2010-04-03 12:21:23 UTC
How would you go about measuring if this is doing any good?
Comment 5 drago01 2010-04-03 12:27:56 UTC
(In reply to comment #4)
> How would you go about measuring if this is doing any good?

I did using Colin' systemtap scripts.

When going to the overview and coming back the number of gjs proxies kept growing.

I failed to find any leaks when reading the code (I had the StThemeNode fix applied), so I tried calling global.gc() in overview._hideDone() and this fixed the problem (i.e the JS proxies where gone when leaving the overview) and memory usage did not increase every time when going to the overview.

We talked on IRC about it and we agreed that global.gc() is to expensive to be called in a situation like this. I searched for an alternative and found JS_MaybeGC which seems better suited for this kind of usage.

With this two patches applied the proxies do not go away immediately after leaving the overview but they do not accumulate overtime.
Comment 6 Colin Walters 2010-04-03 15:14:23 UTC
Review of attachment 157800 [details] [review]:

Looks fine
Comment 7 Colin Walters 2010-04-03 15:24:11 UTC
Review of attachment 157804 [details] [review]:

::: js/ui/main.js
@@ +165,3 @@
+     * Call maybe_gc on idle to free up memory and prevent it from being
+    /*
+

I don't like this, it forces mutter to be scheduled even if we're totally idle.

Slightly better would be to say queue a timeout for some time (10s? 30s?) after an X event (if one isn't scheduled already).
Comment 8 drago01 2010-04-03 15:53:24 UTC
(In reply to comment #7)
> Review of attachment 157804 [details] [review]:
> 
> ::: js/ui/main.js
> @@ +165,3 @@
> +     * Call maybe_gc on idle to free up memory and prevent it from being
> +    /*
> +
> 
> I don't like this, it forces mutter to be scheduled even if we're totally idle.
> 
> Slightly better would be to say queue a timeout for some time (10s? 30s?) after
> an X event (if one isn't scheduled already).

Yeah I am not really sure when we should call this without waking up unnecessarily.
Comment 9 drago01 2010-05-21 12:29:03 UTC
Created attachment 161635 [details] [review]
Call shell_global_maybe_gc() when no work is being done

Call shell_global_maybe_gc in shell_global_end_work() when no other work
is ongoing to free up memory and improve performance by preventing the GC
from kicking in at less convenient times.

See: https://developer.mozilla.org/en/SpiderMonkey/JSAPI_Reference/JS_MaybeGC
Comment 10 Owen Taylor 2010-05-21 19:25:39 UTC
Review of attachment 161635 [details] [review]:

::: src/shell-global.c
@@ +1554,3 @@
+  if (global->work_count == 0)
+    {
+      shell_global_maybe_gc (global);

You definitely want to do this in the idle instead of right here - the work count going to zero doesn't mean that we are at leisure, it just means that we could be at leisure if there isn't other stuff going on.
Comment 11 drago01 2010-05-21 20:18:54 UTC
Created attachment 161679 [details] [review]
Call shell_global_maybe_gc() when no work is being done

*) Do the gc call in idle rather than directly in 
shell_global_end_work
Comment 12 Owen Taylor 2010-05-21 21:07:12 UTC
Review of attachment 161679 [details] [review]:

What I meant was:

===
static gboolean
run_leisure_functions (gpointer data)
{
  ShellGlobal *global = data;
  GSList *closures;
  GSList *iter;

  global->leisure_function_id = 0;

  /* We started more work since we scheduled the idle */
  if (global->work_count > 0)
    return FALSE;

>>> YOUR STUFF GOES HERE

  closures = global->leisure_closures;
====
Comment 13 drago01 2010-05-21 21:13:44 UTC
(In reply to comment #12)
> Review of attachment 161679 [details] [review]:
> 
> What I meant was:
> 
> ===
> static gboolean
> run_leisure_functions (gpointer data)
> {
>   ShellGlobal *global = data;
>   GSList *closures;
>   GSList *iter;
> 
>   global->leisure_function_id = 0;
> 
>   /* We started more work since we scheduled the idle */
>   if (global->work_count > 0)
>     return FALSE;
> 
> >>> YOUR STUFF GOES HERE
> 
>   closures = global->leisure_closures;
> ====

Well this would only be called when leisure functions are registered, no?

This is called by schedule_leisure_functions when global->leisure_closures is not NULL ... so it wouldn't quite do what I intend to do with it (it shouldn't run only when collecting statistics).
Comment 14 Owen Taylor 2010-05-21 21:18:18 UTC
(In reply to comment #13)
> (In reply to comment #12)
> > Review of attachment 161679 [details] [review] [details]:
> > 
> > What I meant was:
> > 
> > ===
> > static gboolean
> > run_leisure_functions (gpointer data)
> > {
> >   ShellGlobal *global = data;
> >   GSList *closures;
> >   GSList *iter;
> > 
> >   global->leisure_function_id = 0;
> > 
> >   /* We started more work since we scheduled the idle */
> >   if (global->work_count > 0)
> >     return FALSE;
> > 
> > >>> YOUR STUFF GOES HERE
> > 
> >   closures = global->leisure_closures;
> > ====
> 
> Well this would only be called when leisure functions are registered, no?
> 
> This is called by schedule_leisure_functions when global->leisure_closures is
> not NULL ... so it wouldn't quite do what I intend to do with it (it shouldn't
> run only when collecting statistics).

If you want to do this always, leisure functions or not, then just make the code do that, rather than adding a duplicate idle function.
Comment 15 drago01 2010-05-21 21:29:30 UTC
(In reply to comment #14)
> (In reply to comment #13)
> > (In reply to comment #12)
> [..]
> If you want to do this always, leisure functions or not, then just make the
> code do that, rather than adding a duplicate idle function.

This kind of makes sense ...
Comment 16 drago01 2010-05-21 21:30:11 UTC
Created attachment 161685 [details] [review]
Call shell_global_maybe_gc() when no work is being done

Do the call in run_leisure_functions, and change the code to always
call it when there is no work left.
Comment 17 Owen Taylor 2010-05-21 21:42:21 UTC
Review of attachment 161685 [details] [review]:

OK, this looks good ("prevent to run" => "prevent from running" in a comment.)

I'm not completely sure I understand how this fits in to the big picture of garbage collection, and I haven't seen any problem with GC pauses, but let's try it this way and see how it goes.
Comment 18 drago01 2010-05-21 21:49:04 UTC
Attachment 161685 [details] pushed as ce3f003 - Call shell_global_maybe_gc() when no work is being done