在iOS上强制JavaScriptCore虚拟机的垃圾收集

sil*_*vsk 5 macos garbage-collection ios javascriptcore

有没有办法强制iOS(或Mac OS)JavaScriptCore VM垃圾收集器运行?我只需要测试内存泄漏,所以私有API就可以了.

Bor*_*kyi 5

使用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);
Run Code Online (Sandbox Code Playgroud)

您可以使用readonly属性JSContextRef从您那里获得.JSContextJSGlobalContextRef

更新

我在WebKit中找到了下一个更改 - bugs.webkit.org/show_bug.cgi?id=84476:

JSGarbageCollect不应同步调用collectAllGarbage().相反,它应该通知GCActivityCallback它已经放弃了一个对象图,它将把计时器设置为在未来的某个时刻运行,JSC可以根据自己的策略来决定.

这解释了为什么以前的解决方案不能按预期工作.

深入研究WebKit源代码,我发现了另一种有趣的方法.请尝试以下代码:

JS_EXPORT void JSSynchronousGarbageCollectForDebugging(JSContextRef ctx);

@interface JSContext (GarbageCollection)

-(void)garbageCollect {
    JSSynchronousGarbageCollectForDebugging(self.JSGlobalContextRef);
}

@end
Run Code Online (Sandbox Code Playgroud)

之后只需garbageCollect在您的JSContext实例上调用方法.我已经在iOS上本地尝试了它,它似乎工作.