Is there any way to force iOS (or Mac OS) JavaScriptCore VM garbage collector to run? I need it only to test for memory leaks, so private API would be fine.
Java Mission Control and JConsole both have visual tools that allow you to force Java GC. While a developer can never actually force Java garbage collection, there are ways to make the JVM prioritize memory management functions. In review, five ways to try and force Java garbage collection are: Call the System.gc () command.
Detailed examples to follow. There’s a background process in the JavaScript engine that is called garbage collector. It monitors all objects and removes those that have become unreachable. Here the arrow depicts an object reference. The global variable "user" references the object {name: "John"} (we’ll call it John for brevity).
If you are familiar with low-level programming, more detailed information about V8’s garbage collector is in the article A tour of V8: Garbage Collection. The V8 blog also publishes articles about changes in memory management from time to time.
Developers can call System.gc () anywhere in their code to instruct the JVM to prioritize garbage collection. When a developer calls this method -- and there isn't an extreme load on the JVM -- a Java GC cycle will happen within seconds. 2. Call Runtime.getRuntime ().gc () Another option is to use the Runtime.getRuntime ().gc () call.
Use following function from JSBase.h:
/*!
@function JSGarbageCollect
@abstract Performs a JavaScript garbage collection.
@param ctx The execution context to use.
@discussion JavaScript values that are on the machine stack, in a register,
protected by JSValueProtect, set as the global object of an execution context,
or reachable from any such value will not be collected.
During JavaScript execution, you are not required to call this function; the
JavaScript engine will garbage collect as needed. JavaScript values created
within a context group are automatically destroyed when the last reference
to the context group is released.
*/
JS_EXPORT void JSGarbageCollect(JSContextRef ctx);
You can obtain JSContextRef
from your JSContext
, using JSGlobalContextRef
readonly property.
Update
I've found next change in WebKit - bugs.webkit.org/show_bug.cgi?id=84476:
JSGarbageCollect should not synchronously call collectAllGarbage(). Instead, it should notify the GCActivityCallback that it has abandoned an object graph, which will set the timer to run at some point in the future that JSC can decide according to its own policies.
This explains why previous solution doesn't work as expected.
Digging deeper into WebKit sources, I found another interesting approach. Please, try following code:
JS_EXPORT void JSSynchronousGarbageCollectForDebugging(JSContextRef ctx);
@interface JSContext (GarbageCollection)
-(void)garbageCollect {
JSSynchronousGarbageCollectForDebugging(self.JSGlobalContextRef);
}
@end
Simply call garbageCollect
method on your JSContext
instance after that. I've tried it locally on iOS and it seems to work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With