Re: Memory tracking in GJS

2014-03-03 Thread Andy Wingo
On Sun 02 Mar 2014 22:39, Colin Walters  writes:

> On Sun, Mar 2, 2014 at 3:37 PM, Andy Wingo  wrote:
>
> Ideally GLib could define an interface void g_register_allocation
> (size_t bytes, char *for_whom);
>
> What about GLib libraries which wrap non-GLib libraries that do the
> heavy lifting? For example, the gjs wrappers for cairo.

You just have to guess :/ In the case of cairo you can estimate based on
surface size and configured bit depth.  Guessing is fine in this case.

> I think we're still going to need a multi-pronged approach, with an
> explicit dispose API, running large allocations through an API like the
> one you proposed, as well as kernel level support for hints about a good
> time to GC (and how much time to spend doing so).

Could be, yes.  Kernel support probably makes more sense with a moving
GC, which is part of upstream SM but not enabled yet.  Otherwise a GC
could see reports of memory consumption Y, from the kernel's
perspective, but really a GC can't do anything about it because of
fragmentation.

Anyway, unfortunately I don't have time to help at the moment.  I'm
happy to chat about these things though if you need someone to bounce
ideas off.

Cheers,

Andy
-- 
http://wingolog.org/
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Memory tracking in GJS

2014-03-02 Thread Colin Walters

On Sun, Mar 2, 2014 at 3:37 PM, Andy Wingo  wrote:


Ideally GLib could define an interface

  void g_register_allocation (size_t bytes, char *for_whom);

What about GLib libraries which wrap non-GLib libraries that do the 
heavy lifting?  For example, the gjs wrappers for cairo.


I think we're still going to need a multi-pronged approach, with an 
explicit dispose API, running large allocations through an API like the 
one you proposed, as well as kernel level support for hints about a 
good time to GC (and how much time to spend doing so).



___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Memory tracking in GJS

2014-03-02 Thread Andy Wingo
Hi,

A little late here.  SM's GC needs to know about all allocations that it
might collect, both those that it can trace and those that it can't.
Ideally GLib could define an interface

  void g_register_allocation (size_t bytes, char *for_whom);

and GJS should register some listener on that allocation recorder, which
then bumps SM's mallocation counter (which would then cause GC to happen
more frequently -- but not "all the time", rather when needed.  Of
course then you have to patch gdk-pixbuf and everyone else to record
allocations, but that's cheap and doable -- basically it's just
gdk-pixbuf and the slice allocator anyway, no?

To do otherwise is to solve most problems but leave some pathological
cases unhandled.

Regards,

Andy
-- 
http://wingolog.org/
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Memory tracking in GJS

2014-02-25 Thread Cosimo Cecchi
On Tue, Feb 25, 2014 at 11:08 AM, Bastien Nocera  wrote:

> On Mon, 2014-02-24 at 13:56 -0800, Cosimo Cecchi wrote:
> > Thanks all for your inputs; I now posted a first iteration of a patch
> > that implements the suggestions of this thread here
> >
> >
> > https://bugzilla.gnome.org/show_bug.cgi?id=725099
>
> This is pretty similar to Giovanni's patch, no?
>
> https://bugzilla.gnome.org/show_bug.cgi?id=724797


Only partly; the last patch of Giovanni's just calls JS_MaybeGC(), which
won't look at the memory allocation as reported by the kernel, whereas my
patch will schedule a call to gjs_maybe_gc(), which also has the logic
Colin linked to before. I also schedule that from a bunch more places than
Giovanni's patch did.

Cheers,
Cosimo
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Memory tracking in GJS

2014-02-25 Thread Bastien Nocera
On Mon, 2014-02-24 at 13:56 -0800, Cosimo Cecchi wrote:
> Thanks all for your inputs; I now posted a first iteration of a patch
> that implements the suggestions of this thread here
> 
> 
> https://bugzilla.gnome.org/show_bug.cgi?id=725099

This is pretty similar to Giovanni's patch, no?

https://bugzilla.gnome.org/show_bug.cgi?id=724797

Cheers


___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Memory tracking in GJS

2014-02-24 Thread Cosimo Cecchi
Thanks all for your inputs; I now posted a first iteration of a patch that
implements the suggestions of this thread here

https://bugzilla.gnome.org/show_bug.cgi?id=725099

Cheers,
Cosimo


On Thu, Feb 20, 2014 at 6:09 AM, Colin Walters  wrote:

> On Wed, Feb 19, 2014 at 8:50 PM, Cosimo Cecchi  wrote:
>
> Hi all,
>
> The state of garbage collection for typical GTK/JS applications is pretty
> sad these days.
>
>
> It's worth a comparison with (C)Python.   In some ways, Python's hybrid
> refcount + GC is the worst of both worlds - you have the constant overhead
> (cacheline bouncing, etc.) hit of refcounting, with the unpredictability of
> GC as soon as you happen to make a reference cycle.
>
> Except for the case of objects allocated in local function scope.  This
> case is a very important one for us.  Many of my applications do this a
> *lot* - lots of Gio.File instances for example.  And stuff like Cairo
> surfaces.   (C)Python will deterministically clean these up at the end of
> the function - they don't escape, their refcount drops to 0.
>
> It'd be quite nice if the Spidermonkey compiler attempted to do escape
> analysis and deterministic cleanup when it could.
>
> The problem is that for a native GObject wrapped into a JSObject there are
> effectively two sets of allocations: those internal to GObject and those
> needed to wrap it into a JSObject. While in the latter case the garbage
> collector will keep track of those segments, we currently never forward the
> GObject allocations/payload size to the garbage collector.
>
>
> I don't think we can ever do that in a reliable way.  At least with the
> current design of GObject.
>
> Now...the Samba guys are heavily invested in talloc (
> http://talloc.samba.org/talloc/doc/html/index.html ) which gives this
> kind of information for effectively free ( talloc_get_size () ).
>
> I've thought sometimes about having an optional talloc-like API for GLib,
> but it would be really invasive.
>
> The result is that, especially with large objects (e.g. pixbufs, cairo
> surfaces, ...) there's a huge difference between what mozjs thinks is the
> memory situation and the reality, and an application can effectively run
> out of system memory before the garbage collector kicks in. Firefox gets
> away with it because JS code only needs to allocate memory outside of the
> garbage collector very rarely, and those cases are handled internally by
> manually updating the counter.
>
>
> It depends on the JS code, but certainly a lot of real-world web pages do
> heavy DOM manipulation which does involve lots of nontrivially-sized native
> objects.  This is the case that every web browser is optimized for, because
> they have to.
>
> Some ideas that have been floating around:
> * have special methods on "interesting" objects to explicitly release
> memory. gnome-shell for instance does this already when using Cairo from
> within JS, for exactly the same reason.
>
>
> I think there's no question we should allow this.  It's a bit ugly, but
>
> * override the GLib memory allocator with e.g. g_mem_set_vtable() to
> intercept allocations and signal the garbage collector. Problems: doesn't
> work for things that use e.g. static constructors, is tricky for
> re-entrancy, libraries like GdkPixbuf might not use the GLib allocator for
> image payloads, doesn't work with the slice allocator.
>
>
> I'd really rather investigate something like talloc-for-glib if we were to
> try going down this route.  It would have the potential to improve
> performance of pure C apps as well.
>
> * keep track of memory allocated in GJS itself. We can use GType to query
> the size of the instance, class and even the size of private data. This
> still doesn't include additional allocations inside the object itself, such
> as strings, buffers and payloads. We could track those case-by-case by e.g.
> overriding constructors in the binding for "interesting" pixbuf-like types
> (ugh), or have a way to query that information from the type
> system/introspection itself.
>
>
> I just don't think this one is going to scale.
>
> Any other ideas?
>
>
> Beyond the above, I think ultimately this needs help from the kernel.
>  That's where I was going with
>
> https://git.gnome.org/browse/gjs/commit/?id=7aae32d1df14af87e9a31c785447b27012b64af9
> Here the kernel is keeping track of our total memory usage, both JS and C.
>
> I feel this is a fundamental enough issue that there must be a good way to
> design a generic solution.
>
>
> It all gets a lot more interesting when you consider *multiple* garbage
> collected processes on the system.  I think this is still an open research
> area.
>
>
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Memory tracking in GJS

2014-02-20 Thread Colin Walters
On Wed, Feb 19, 2014 at 8:50 PM, Cosimo Cecchi  
wrote:

Hi all,

The state of garbage collection for typical GTK/JS applications is 
pretty sad these days.




It's worth a comparison with (C)Python.   In some ways, Python's hybrid 
refcount + GC is the worst of both worlds - you have the constant 
overhead (cacheline bouncing, etc.) hit of refcounting, with the 
unpredictability of GC as soon as you happen to make a reference cycle.


Except for the case of objects allocated in local function scope.  This 
case is a very important one for us.  Many of my applications do this a 
*lot* - lots of Gio.File instances for example.  And stuff like Cairo 
surfaces.   (C)Python will deterministically clean these up at the end 
of the function - they don't escape, their refcount drops to 0.


It'd be quite nice if the Spidermonkey compiler attempted to do escape 
analysis and deterministic cleanup when it could.


The problem is that for a native GObject wrapped into a JSObject 
there are effectively two sets of allocations: those internal to 
GObject and those needed to wrap it into a JSObject. While in the 
latter case the garbage collector will keep track of those segments, 
we currently never forward the GObject allocations/payload size to 
the garbage collector.




I don't think we can ever do that in a reliable way.  At least with the 
current design of GObject.


Now...the Samba guys are heavily invested in talloc ( 
http://talloc.samba.org/talloc/doc/html/index.html ) which gives this 
kind of information for effectively free ( talloc_get_size () ).


I've thought sometimes about having an optional talloc-like API for 
GLib, but it would be really invasive.


The result is that, especially with large objects (e.g. pixbufs, 
cairo surfaces, ...) there's a huge difference between what mozjs 
thinks is the memory situation and the reality, and an application 
can effectively run out of system memory before the garbage collector 
kicks in. Firefox gets away with it because JS code only needs to 
allocate memory outside of the garbage collector very rarely, and 
those cases are handled internally by manually updating the counter.




It depends on the JS code, but certainly a lot of real-world web pages 
do heavy DOM manipulation which does involve lots of nontrivially-sized 
native objects.  This is the case that every web browser is optimized 
for, because they have to.



Some ideas that have been floating around:
* have special methods on "interesting" objects to explicitly release 
memory. gnome-shell for instance does this already when using Cairo 
from within JS, for exactly the same reason.




I think there's no question we should allow this.  It's a bit ugly, but 

* override the GLib memory allocator with e.g. g_mem_set_vtable() to 
intercept allocations and signal the garbage collector. Problems: 
doesn't work for things that use e.g. static constructors, is tricky 
for re-entrancy, libraries like GdkPixbuf might not use the GLib 
allocator for image payloads, doesn't work with the slice allocator.




I'd really rather investigate something like talloc-for-glib if we were 
to try going down this route.  It would have the potential to improve 
performance of pure C apps as well.


* keep track of memory allocated in GJS itself. We can use GType to 
query the size of the instance, class and even the size of private 
data. This still doesn't include additional allocations inside the 
object itself, such as strings, buffers and payloads. We could track 
those case-by-case by e.g. overriding constructors in the binding for 
"interesting" pixbuf-like types (ugh), or have a way to query that 
information from the type system/introspection itself.




I just don't think this one is going to scale.


Any other ideas?



Beyond the above, I think ultimately this needs help from the kernel.  
That's where I was going with

https://git.gnome.org/browse/gjs/commit/?id=7aae32d1df14af87e9a31c785447b27012b64af9
Here the kernel is keeping track of our total memory usage, both JS and 
C.


I feel this is a fundamental enough issue that there must be a good 
way to design a generic solution.


It all gets a lot more interesting when you consider *multiple* garbage 
collected processes on the system.  I think this is still an open 
research area.



___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Memory tracking in GJS

2014-02-20 Thread Ryan Lortie
hi,

On Thu, Feb 20, 2014, at 7:53, Giovanni Campagna wrote:
> It's worth pointing out that mozjs will *force* a garbage collect if
> you go over the malloc limit (a dynamic value between 30 and 90 MB),
> but will garbage collect a lot more often if you call MaybeGC.

My preferred solution to the problem involves doing this, perhaps from a
very low priority idle, once the mainloop has stopped spinning.

I think any proposal that involves a sort of 'information API' where
'well behaved' classes are supposed to provide memory usage information
is probably going to be very burdensome.

Just to explore an example, a bit: let's say that we really strictly
wanted to limit our scope and apply this logic *only* to pixbufs,
because we identified those to be a problematic area.  We now either
need to do one of two things:

 - keep track of all pixbuf allocations in the program so that gjs can
 query a list and use this information to decide to do more GC

 - wire this interface through to the public API of any object that
 holds a pixbuf within itself, and through to the APIs of objects that
 hold those objects (etc.) in order to make this information visible on
 the actual objects held by gjs


I consider the first alternative to be excessively evil.  It's also
unlikely to be able to give you the information you really need -- sure,
we have 100MB of pixbufs allocated, but they might be in places that GC
wouldn't help you.

The second alternative is just entirely too much work to expect of every
class that might stand between a pixbuf and a public API -- and we've
only limited our scope to pixbufs already.  It's also problematic from a
(perhaps pedantic) accounting standpoint: if two objects reference a
shared pixbuf (or intermediate object) then who gets to claim the memory
use as their own?


The other allocation-based alternatives sound like possibilities, but
perhaps are very much too brittle.  For what it's worth, I'm happy to
try to find a way to make disabling the slice allocator and adding a
memory vtable possible again...

Is Giovanni's proposal workable?

Cheers
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Memory tracking in GJS

2014-02-20 Thread Colin Walters
On Thu, Feb 20, 2014 at 7:53 AM, Giovanni Campagna 
 wrote:


We can probably look into mallinfo() as well, 


Been there, done that:

https://git.gnome.org/browse/gjs/commit/?id=7aae32d1df14af87e9a31c785447b27012b64af9



___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Memory tracking in GJS

2014-02-20 Thread Giovanni Campagna
2014-02-20 2:50 GMT+01:00 Cosimo Cecchi :
> Hi all,
>
> The state of garbage collection for typical GTK/JS applications is pretty
> sad these days. mozjs will execute a garbage collection run when it thinks
> around 30MB of allocations have been done.

It's worth pointing out that mozjs will *force* a garbage collect if
you go over the malloc limit (a dynamic value between 30 and 90 MB),
but will garbage collect a lot more often if you call MaybeGC. Firefox
does that at the end of the every user script (with a comment saying
it's for sunspider), maybe we can do the same in gjs?
Additionally, gjs does not support the more advanced forms of GC, so
they trigger less often and block longer. See #724797 for incremental
GC for example.

> Any other ideas? I feel this is a fundamental enough issue that there must
> be a good way to design a generic solution.

We can probably look into mallinfo() as well, it offers a reasonable
estimate of the memory usage for a single threaded application
(because most allocations happen from the main arena).

Giovanni
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Memory tracking in GJS

2014-02-20 Thread Lionel Landwerlin

Hey Cosimo,

Nice to see someone looking at this issue.

On 20/02/14 01:50, Cosimo Cecchi wrote:
* keep track of memory allocated in GJS itself. We can use GType to 
query the size of the instance, class and even the size of private 
data. This still doesn't include additional allocations inside the 
object itself, such as strings, buffers and payloads. We could track 
those case-by-case by e.g. overriding constructors in the binding for 
"interesting" pixbuf-like types (ugh), or have a way to query that 
information from the type system/introspection itself.


Adding on this, I have to mention my experience with OpenGL allocated 
textures.
These often end up being completely outside of the process' address 
space (so completely invisible) and only represented by a very thin 
object in GObject/Gjs.


-
Lionel
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Memory tracking in GJS

2014-02-19 Thread Sam Spilsbury
Hi,

On Thu, Feb 20, 2014 at 9:50 AM, Cosimo Cecchi  wrote:
>
> Any other ideas? I feel this is a fundamental enough issue that there must
> be a good way to design a generic solution.

Something else that's quite controversial would be to add a new,
optional virtual function to GObjectClass to query the amount of
memory used by the object at any given time. Only the object itself,
which has knowledge of its private details, is able to determine this
information reliably.

There's only two situations when it might not be able to do this:
 - 1. When it has pointers to other GObject objects with private data,
in which case it can just call through the same virtual function and
accumulate memory.
 - 2. When it has pointers to other non-GObject objects with private
data, in which case it will need to provide an estimate.

Its controversial because we'd effectively be pushing the reporting
responsibility to the objects itself, but every solution which I've
come across for this so far is either unreliable or not something we'd
want in a production release.

This isn't exactly a completely solvable problem because there's no
one place that we can override and track all allocation, which is kind
of what mozjs' garbage collector wants. Best thing we can do is
provide an estimate.

Sam.

>
> Cheers,
> Cosimo
>
> ___
> gtk-devel-list mailing list
> gtk-devel-list@gnome.org
> https://mail.gnome.org/mailman/listinfo/gtk-devel-list
>



-- 
Sam Spilsbury
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list


Memory tracking in GJS

2014-02-19 Thread Cosimo Cecchi
Hi all,

The state of garbage collection for typical GTK/JS applications is pretty
sad these days. mozjs will execute a garbage collection run when it thinks
around 30MB of allocations have been done.
The problem is that for a native GObject wrapped into a JSObject there are
effectively two sets of allocations: those internal to GObject and those
needed to wrap it into a JSObject. While in the latter case the garbage
collector will keep track of those segments, we currently never forward the
GObject allocations/payload size to the garbage collector.
The result is that, especially with large objects (e.g. pixbufs, cairo
surfaces, ...) there's a huge difference between what mozjs thinks is the
memory situation and the reality, and an application can effectively run
out of system memory before the garbage collector kicks in. Firefox gets
away with it because JS code only needs to allocate memory outside of the
garbage collector very rarely, and those cases are handled internally by
manually updating the counter.

Some ideas that have been floating around:
* have special methods on "interesting" objects to explicitly release
memory. gnome-shell for instance does this already when using Cairo from
within JS, for exactly the same reason.
* override the GLib memory allocator with e.g. g_mem_set_vtable() to
intercept allocations and signal the garbage collector. Problems: doesn't
work for things that use e.g. static constructors, is tricky for
re-entrancy, libraries like GdkPixbuf might not use the GLib allocator for
image payloads, doesn't work with the slice allocator.
* override/intercept allocations with a LD_PRELOAD hack. Pretty evil and
brittle.
* keep track of memory allocated in GJS itself. We can use GType to query
the size of the instance, class and even the size of private data. This
still doesn't include additional allocations inside the object itself, such
as strings, buffers and payloads. We could track those case-by-case by e.g.
overriding constructors in the binding for "interesting" pixbuf-like types
(ugh), or have a way to query that information from the type
system/introspection itself.

Any other ideas? I feel this is a fundamental enough issue that there must
be a good way to design a generic solution.

Cheers,
Cosimo
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-devel-list