On Wed, Feb 19, 2014 at 8:50 PM, Cosimo Cecchi <cosi...@gnome.org>
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