V8 如何使用 requestAnimationFrame 重建异步堆栈跟踪?

Jon*_*lms 5 javascript v8 google-chrome-devtools

根据零成本异步堆栈跟踪, V8 使用微任务中的 Promise 引用来重建“异步堆栈跟踪”。我假设调试器中也使用了类似的技术,它也显示了“异步堆栈”。然而,当调试“伪递归函数”时,例如使用以下函数requestAnimationFrame

(function tick() { requestAnimationFrame(tick); })();
Run Code Online (Sandbox Code Playgroud)

然后 Chrome 还显示了一些“异步堆栈”,如这个问题所示,尽管没有 Promise 存在。V8 如何恢复这个堆栈?它是否收集有关如何安排微任务的信息?如果是这样,什么可以防止内存泄漏?

Ben*_*aum 3

基本上都是骗人的。打开 devtools 时,使用 chrome devtools 协议的调试器将连接到 v8。

它反过来调用setAsyncCallStackDepth,每当异步调用完成时,它将“缝合”堆栈(您可以在 chromium 存储库中的 v8/src/inspector/v8-debugger.cc 中查看如何操作)。

它很昂贵,这就是为什么你只能在开发工具中获得它。

您可以将其视为:

  • 每当调用异步函数时,请通过堆栈跟踪来跟踪它。
  • 当抛出错误时,获取其堆栈跟踪并将两者“缝合”在一起。

请注意,这是之前在用户层库中完成的(例如 bluebird),并且非常有用,但在生产应用程序中不太依赖,因为它仅适用于连接的调试器。