W3C home > Mailing lists > Public > public-webapps@w3.org > January to March 2011

Re: [IndexedDB] setVersion blocked on uncollected garbage IDBDatabases

From: Glenn Maynard <glenn@zewt.org>
Date: Wed, 9 Feb 2011 20:26:13 -0500
Message-ID: <AANLkTimAW1cS7=q53yD9RCmEYAHWQ-0v5Xq-=7QiL_5w@mail.gmail.com>
To: Drew Wilson <atwilson@google.com>
Cc: Jonas Sicking <jonas@sicking.cc>, Jeremy Orlow <jorlow@chromium.org>, ben turner <bent.mozilla@gmail.com>, João Eiras <joao.eiras@gmail.com>, public-webapps <public-webapps@w3.org>
On Wed, Feb 9, 2011 at 5:05 PM, Drew Wilson <atwilson@google.com> wrote:

> In some cases we leak them, yes (they live for the life of the parent
> context) if the developer does not close them. Typically this is only when
> you've cloned a MessagePort and sent the other end to a different process.
> Trying to figure out if a port is reachable when the entangled port lives in
> a different process (and whose reachability may itself depend on the
> reachability of a third port in yet another process ad infinitum) is a
> fairly intractable problem.

OK.  At least the heap snapshotting in Chrome is good enough to make
debugging this reasonably easy, if it results in nontrivial leaks.

>  This does not happen with the implicit ports associated with dedicated
> workers, because in WebKit those aren't actually MessagePorts (mainly
> because the webkit implementation of dedicated workers predates message
> ports). Chromium SharedWorkers use real MessagePorts though, so if you do
> this:
> var w = new SharedWorker("foo.html");
> w.port.onmessage = function() {...};
> that port will not be GC'd in chromium, even if the SharedWorker drops its
> end of the port on the floor, until either the SharedWorker calls close() on
> the port, the worker exits or your parent document is collected.

That's natural, of course--the event handler holds a reference to the

On a related note, please see this statement from section 5.5 of the
> MessagePort spec:
> Authors are strongly encouraged to explicitly close MessagePort<http://dev.w3.org/html5/postmsg/#messageport> objects
> to disentangle them, so that their resources can be recollected. Creating
> many MessagePort <http://dev.w3.org/html5/postmsg/#messageport> objects
> and discarding them without closing them can lead to high memory usage.

For explicitly-created MessagePorts this is natural enough.  It's slightly
less obvious for MessagePorts created implicitly by Worker/SharedWorker
objects, though; I'd predict that becoming a common cause of leaks on pages
that create and destroy a lot of threads.

Back on IDB: If one page has an opened database (whether from not being
closed, a GC issue, or a simpler site issue), and a new tab is failing to
setVersion as a result, figuring out the cause may be painful.  Hopefully
browsers will at least be able to tell which other tab is holding the
database open, and retrieve a stack trace of where it was opened, even if
it's in a closed tab.  If that information is available, it would be useful
to include it in the "blocked" event, as an optional, informative message
that scripts can send to their server-side error logging if it blocks for
too long.

Another related issue: what happens if a long-running number-cruncher worker
keeps a database open while it works, to read data or output results?
There's no API for sending versionchange events for IDBDatabaseSync, and it
doesn't fit in any obvious way since it's inherently asynchronous.  I
suppose the developer-side workaround would be to open the same database
asynchronously in the UI thread just to listen for versionchange, and to
terminate the thread when it's received.  Is that generally what's intended?

Glenn Maynard
Received on Thursday, 10 February 2011 01:29:29 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 18:13:16 UTC