Weak References in node/V8

364 views
Skip to first unread message

Tim Caswell

unread,
Nov 30, 2009, 5:03:24 PM11/30/09
to nod...@googlegroups.com
I'm working on a simple database written in pure JavaScript. I want to persist my data in json files, but cache the contents in memory once accessed. A problem I'm running into is I don't know when to let go of the cache.

I've used weak references in other languages and this would be an ideal solution since the GC would manage clearing the cache for me when memory use got high.

Does anyone know by chance if such a feature exists in V8 or is there a way to simulate is via userland code? At worst case I'll write a simple userland GC for my cache that clears cache objects that haven't been used in a while. Once they're not referenced anymore the real GC should eventually grab them.

If I do go this route I'll want to know things like the current memory usage and/or heap size so I know when to start reaping cache tables.

Anyone have any ideas?

http://en.wikipedia.org/wiki/Weak_reference#Garbage_collection

Ryan Dahl

unread,
Nov 30, 2009, 11:23:55 PM11/30/09
to nodejs
On Mon, Nov 30, 2009 at 11:03 PM, Tim Caswell <t...@creationix.com> wrote:
> I'm working on a simple database written in pure JavaScript.  I want to persist my data in json files, but cache the contents in memory once accessed.  A problem I'm running into is I don't know when to let go of the cache.
>
> I've used weak references in other languages and this would be an ideal solution since the GC would manage clearing the cache for me when memory use got high.
>
> Does anyone know by chance if such a feature exists in V8 or is there a way to simulate is via userland code?  At worst case I'll write a simple userland GC for my cache that clears cache objects that haven't been used in a while.  Once they're not referenced anymore the real GC should eventually grab them.

You can get information about weak references from the C++ side, but
not from the javascript side - as far as I know. You might want to ask
on the V8 users mailing list if there is some hack to get the
reference count from within javascript.

> If I do go this route I'll want to know things like the current memory usage and/or heap size so I know when to start reaping cache tables.

I recently added information about the v8 heap size to process.memoryUsage()

Bert Belder

unread,
Dec 1, 2009, 5:09:04 PM12/1/09
to nodejs
process.memoryUsage() is absolutely necessary to check if the memory
is getting full, but the question remains *when* it's time to check
the memory usage and possibly start flushing cache entries. Obviously
you could just check the memory usage on a fixed interval, but then
there would be no way to account for the fact that the garbage
collector may be about to free up memory as well, which could make the
cache flush unnecessary.

I think it would be better to sync the cache clearing with the garbage
collector, so maybe a system event that is raised when the garbage
collector starts or finishes a cycle is the way to go. Then you could
just hook up an event that checks the memory usage just after a GC
cycle.

- Bert

Bert Belder

unread,
Dec 1, 2009, 6:04:17 PM12/1/09
to nodejs
process.memoryUsage() is absolutely needed in order to determine if
cache flushing is necessary, but the question remains when to check
the memory usage. Obviously you could simply check the memory usage on
a fixed interval and clear the cache if needed, but then you cannot
account for the fact that the garbage collector may be about to free
up memory as well. Therefore I think it would be better to sync the
memory check/cache flush with the garbage collector, making sure that
cache entries are freed just after the garbage collector enters a
cycle. Isn't it an idea to have the process object raise an event when
the garbage collector starts or finishes a cycle?

On Dec 1, 5:23 am, Ryan Dahl <coldredle...@gmail.com> wrote:

Ryan Dahl

unread,
Dec 1, 2009, 11:35:03 PM12/1/09
to nodejs
On Tue, Dec 1, 2009 at 11:09 PM, Bert Belder <bertb...@gmail.com> wrote:
> process.memoryUsage() is absolutely necessary to check if the memory
> is getting full, but the question remains *when* it's time to check
> the memory usage and possibly start flushing cache entries. Obviously
> you could just check the memory usage on a fixed interval, but then
> there would be no way to account for the fact that the garbage
> collector may be about to free up memory as well, which could make the
> cache flush unnecessary.
>
> I think it would be better to sync the cache clearing with the garbage
> collector, so maybe a system event that is raised when the garbage
> collector starts or finishes a cycle is the way to go. Then you could
> just hook up an event that checks the memory usage just after a GC
> cycle.

Okay, sure.

In V8 there is already a hook to get a callback before or after a GC.
(SetGlobalGCPrologueCallback() and SetGlobalGCEpilogueCallback().)
This wouldn't be a bad thing to implement as a process event:

process.addListener("beforeGC", ...)
process.addListener("afterGC", ...)

For performance reasons, I don't want to add a C++ level callback
unless there are JS level listeners. But other than that, it should be
straightforward to implement.

I would accept a patch for this feature.
Reply all
Reply to author
Forward
0 new messages