[v8-users] about v8 garbage collection

1,291 views
Skip to first unread message

Camilo Aguilar

unread,
May 6, 2010, 5:09:44 PM5/6/10
to v8-users
I'm currently porting a C Library to Nodejs using de v8 C++ API and I have a big question:

Are the garbage collection heuristics affected due to memory allocations and deallocations inside this C Library ?

If so, how can I let it to know of these allocations/deallocations ?

Camilo Aguilar

--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users

Piero B. Contezini

unread,
May 6, 2010, 5:17:33 PM5/6/10
to v8-u...@googlegroups.com
Look for this function: AdjustAmountOfExternalAllocatedMemory

It should do what you need.

Søren Gjesse

unread,
May 6, 2010, 5:24:34 PM5/6/10
to v8-u...@googlegroups.com
Take a look at the API AdjustAmountOfExternalAllocatedMemory in include/v8.h, I think that is what you are looking at.

Regards,
Søren

Camilo Aguilar

unread,
May 6, 2010, 5:54:56 PM5/6/10
to v8-u...@googlegroups.com
Thank you for your quick answers but what happens if I have a library like libxml, gnutls, c-ares, libvirt, etc. They have theirs own internal memory allocations and deallocations. Does this affect the v8 garbage collection heuristics?
I need to hack each library that I want to use through Javascript to add AdjustAmountOfExternalAllocatedMemory in everyone of them?

Camilo

2010/5/6 Søren Gjesse <sgj...@chromium.org>

Camilo Aguilar

unread,
May 6, 2010, 5:59:47 PM5/6/10
to v8-u...@googlegroups.com
Sorry for my insistence, I'm trying to understand :$.

Eddy Bruël

unread,
May 6, 2010, 7:29:50 PM5/6/10
to v8-u...@googlegroups.com
Hey,

As far as I know, the v8 garbage collection heuristics are *not* affected by memory allocations done by external libraries. That's exactly what AdjustAmountOfExternalAllocatedMemory is for.

Anton Muhin

unread,
May 7, 2010, 1:50:33 AM5/7/10
to v8-u...@googlegroups.com
In Chromium we have additional check points that check memory usage
and trigger GC if it's too high. Take a look at:
http://www.google.com/codesearch/p?hl=ru#oNZLX4WuLx8/trunk/WebKit/WebCore/bindings/v8/V8GCController.cpp&q=v8gccontroller::checkmemoryusage&sa=N&cd=1&ct=rc

This is not the most beatiful piece of code, but it helps with some
rather nasty bugs.

However, before implementing that, why do you need to depend on amout
of externally allocated memory? The principal reason for Chromium is
the case when JS wrappers retain huge natively allocated structures
(esp. when wrappers are thin by themselves). Is it the case for you
or you have some different story?

yours,
anton.

Stephan Beal

unread,
May 7, 2010, 3:40:35 AM5/7/10
to v8-u...@googlegroups.com
On Thu, May 6, 2010 at 11:54 PM, Camilo Aguilar <cam...@cloudescape.com> wrote:
Thank you for your quick answers but what happens if I have a library like libxml, gnutls, c-ares, libvirt, etc. They have theirs own internal memory allocations and deallocations. Does this affect the v8 garbage collection heuristics?

Not directly, no. v8 cannot know how much memory libexpat, curses, etc. allocate for themselves, and the AdjustAmountOfExternalAllocatedMemory() API (try typing that 10 times quickly) is there so we can give v8 a hint about how much we've allocated. For bound C++ types i sometimes add a member, something like "memoryUsage()", which i can use for this purpose, but it is important that you pass the same relative value to AAoEAAM() when incrementing/decrementing the value, to avoid that the allocation hints end up out of sync.

Unless v8 and all bound funcs/classes use the same allocator, there really is no in-language way of knowing how much memory is in use by each component. When importing other libs, which may in fact use their own allocators, the best we can do is guess and give v8 that number. Keep in mind that in C++ library authors can re-implement the 'new' operator, which means that (in theory, though not in practice) a library with 100 classes _could_ use 100 different allocation sources.

That said, for "most" desktop purposes, it's not critical to make v8 aware of memory used by the internals of 3rd-party code. 
 
I need to hack each library that I want to use through Javascript to add AdjustAmountOfExternalAllocatedMemory in everyone of them?

If you _need_ that feature, yes. In my experience, though, it's not critical.

--
----- stephan beal
http://wanderinghorse.net/home/stephan/

Marco Rogers

unread,
May 7, 2010, 9:50:12 AM5/7/10
to v8-users
Thanks Stephen, that's a lot of helpful info. So in regards to
providing v8 with helpful information, what are the implications of
"cheating" with the memory hints? I'm using libxml and there's no
good way to find out exactly how much memory was just allocated when a
node is created. But the library does provide a method that gives the
*total* amount of memory allocated.

http://xmlsoft.org/html/libxml-xmlmemory.html#xmlMemUsed

So rather than trying to be surgical with the calls to AAoEAAM, I was
thinking of maintaining a variable with the total memory used. And
everytime something is allocated or freed then I would decrement by
the previous value, and immediately increment by the new total memory
value. Does anyone see problems with this level of "churn" on the
memory hints?

:Marco
> ----- stephan bealhttp://wanderinghorse.net/home/stephan/
>
> --
> v8-users mailing list
> v8-users@googlegroups.comhttp://groups.google.com/group/v8-users

Stephan Beal

unread,
May 7, 2010, 9:54:35 AM5/7/10
to v8-u...@googlegroups.com
On Fri, May 7, 2010 at 3:50 PM, Marco Rogers <marco....@gmail.com> wrote:
So rather than trying to be surgical with the calls to AAoEAAM, I was
thinking of maintaining a variable with the total memory used.  And
everytime something is allocated or freed then I would decrement by
the previous value, and immediately increment by the new total memory
value.  Does anyone see problems with this level of "churn" on the
memory hints?

That would be my instinct as well. Alternately, you could increase the count when an element is read (e.g. use the XML's length, plus maybe some fudge factor), but that assumes that the elements have a "weak destructor" which allows them to tell v8 about the change when the elements themselves are destroyed. If your elements are C++ bound classes then that probably isn't much work, whereas if they are plain JS objects it would be problematic to capture the destruction for purposes of decrementing the memory use.


--
----- stephan beal

http://wanderinghorse.net/home/stephan/

--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users

Stephan Beal

unread,
May 7, 2010, 9:58:50 AM5/7/10
to v8-u...@googlegroups.com
On Fri, May 7, 2010 at 3:54 PM, Stephan Beal <sgb...@googlemail.com> wrote:
elements themselves are destroyed. If your elements are C++ bound classes then that probably isn't much work, whereas if they are plain JS objects it would be problematic to capture the destruction for purposes of decrementing the memory use.

OTOH, if the elements are "pure JS" then v8 already knows how much memory is used by them. You would only need to track the memory for any native libxml components which you keep around for the life of the parser.

But if it becomes too much of a pain, just keep in mind that this level of management isn't technically necessary - it's just a way to allow v8 to help enforce any hard memory limit by making it aware of external allocation sizes.

Marco Rogers

unread,
May 7, 2010, 10:06:49 AM5/7/10
to v8-u...@googlegroups.com
Yes they're C++ objects.  The problem with trying to read the memory is that libxml has several different structs it uses for different node types.  And I can't tell through the pointer what type it is.  Plus I don't know enough about libxml yet.  I don't know what struct properties to also include in the allocation count.  I don't want to count child nodes and such.  I'm sure it can be done with a lot of research and a lot of checking, but an easier solution would be preferable.

Yes, I would rather let v8 handle things. The reason this is an issue in my instance, is that my users want to be able to allocate huge node trees over and over again in tight loops.  So the memory stacks up fast and v8 doesn't know about it so you chew through your memory before the GC has a chance to run.  I know it can be solved with a good hint system for the GC.  In tests, we were able alleviate the problem by invoking the GC manually at certain intervals.  So the destructors are good, they're just not being called often enough.

I'm probably going to end up with a combination of this cheap hint solution plus Anton's awesome memory checker from Chromium.

Thanks all
:Marco
--
Marco Rogers
marco....@gmail.com

Life is ten percent what happens to you and ninety percent how you respond to it.
- Lou Holtz

Camilo Aguilar

unread,
May 7, 2010, 12:06:51 PM5/7/10
to v8-u...@googlegroups.com
Good discussion, Thank you to everyone. Now I understand better :)
Reply all
Reply to author
Forward
0 new messages