The OS may simply be not reclaiming memory (for performance reasons for example) even if your application has freed it correctly. The application heap may also be holding the memory in case you need it again quickly. Either way, if you're sure you're not leaking (try something like valgrind), I wouldn't worry about it.
How to free up the memory claimed by V8?
-
18-03-2022 - |
Question
An application I'm working on embeds V8 for scripting. To conserve memory, I want to shut down the scripting component when it is not needed, but for some reason the memory is never returned to the OS.
Here's what I tried:
1. Call Dispose() on the persistent context handle
context.Dispose();
2. Force a garbage collection
while (!v8::V8::IdleNotification());
None of that has any notable effect on the processes memory usage. I can clearly see how it's going up when a script claims memory, but it never goes down again.
I'm determining process memory usage with ps -o rss
. I know that figuring out how much memory a process is using is not really possible without a profiler, but I do believe rss should go down when V8 lets go of the memory.
Solution
OTHER TIPS
Just spent few hours wrestling with this and eventually had to dig into api.cc of V8.
Turns out V8 pins last instance of global object template for fast reuse (be it raw ObjectTemplate or one derived from FunctionTemplate for proxies). Which is immensely confusing when trying to force GC flush. Workaround is to allocate new dummy context (using same template as of context you're trying to flush).
static void do_gc()
{
{
Isolate *i = Isolate::GetCurrent();
HandleScope h(i);
Handle<Context> c = Context::New(i); // Default contexes
Handle<Context> c = Context::New(i, 0, objtemplate); // With custom object
Handle<Context> c = Context::New(i, 0, fntemplate->InstanceTemplate()); // With proxy
}
while (!v8::V8::IdleNotification());
}
To see usage in context https://github.com/katlogic/lv8/blob/344353dac702901c917a4c05438252121c527ab3/lv8.cpp#L755