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.
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.
extern "C" JSSynchronousGarbageCollectForDebugging(JSContextRef ctx);
Either the JS_EXPORT
macro has changed, or it depends where this code is used (I'm using it in c++ ios 14) –
Anceline © 2022 - 2024 — McMap. All rights reserved.