我正在对JS Interpreter进行大量修改的fork进行分析,并使用--prof
在node.js v12.12.0上运行,而它运行了一个简短的综合基准。在`node --prof-process'的输出中,我看到程序的63%的运行时都用在C ++中:
[Summary]:
ticks total nonlib name
1503 35.6% 35.9% JavaScript
2658 63.0% 63.4% C++
119 2.8% 2.8% GC
30 0.7% Shared libraries
29 0.7% Unaccounted
特别是,只有一个C ++函数占整个运行时的59%:
[C++]:
ticks total nonlib name
2504 59.3% 59.8% t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
27 0.6% 0.6% T node::native_module::NativeModuleEnv::CompileFunction(v8::FunctionCallbackInfo<v8::Value> const&)
23 0.5% 0.5% T _proc_set_dirty
16 0.4% 0.4% T __kernelrpc_vm_remap
9 0.2% 0.2% t __malloc_initialize
9 0.2% 0.2% T _thread_get_state
8 0.2% 0.2% T node::contextify::ContextifyContext::CompileFunction(v8::FunctionCallbackInfo<v8::Value> const&)
...
不幸的是,对我来说
__ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
可能在做什么并不很明显。该名称表明它与检查器协议有关,但是我没有使用
--inspect
命令行标志,也没有尝试使用检查器将其附加到正在运行的进程中。我似乎在node.js源代码中找不到包含字符串“ NodeRuntime”和“ DispatcherImpl”的任何文件。
它似乎是从几个不同的地方调用的,通常是从自身递归调用的(列表被修剪为主要显示顶级条目的列表),但是命名的JavaScript函数没有任何明显的共性:
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
Callers occupying less than 1.0% are not shown.
ticks parent name
2504 59.3% t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
1287 51.4% t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
785 61.0% LazyCompile: *intrp.Object.defineProperty /Users/cpcallen/src/CodeCity/server/interpreter.js:4477:51
226 17.6% LazyCompile: *intrp.UserFunction.instantiateDeclarations /Users/cpcallen/src/CodeCity/server/interpreter.js:4840:66
67 5.2% LazyCompile: *intrp.Object.getOwnPropertyDescriptor /Users/cpcallen/src/CodeCity/server/interpreter.js:4455:61
34 2.6% t __ZN4node9inspector8protocol11NodeRuntime14DispatcherImplD1Ev
22 1.7% LazyCompile: *stepFuncs_.MemberExpression /Users/cpcallen/src/CodeCity/server/interpreter.js:6582:42
278 11.1% LazyCompile: *Interpreter.run /Users/cpcallen/src/CodeCity/server/interpreter.js:290:37
140 5.6% LazyCompile: *stepFuncs_.Identifier /Users/cpcallen/src/CodeCity/server/interpreter.js:6494:36
121 4.8% LazyCompile: *intrp.UserFunction.instantiateDeclarations /Users/cpcallen/src/CodeCity/server/interpreter.js:4840:66
91 3.6% LazyCompile: ~runBench /Users/cpcallen/src/CodeCity/server/tests/interpreter_bench.js:37:18
79 3.2% LazyCompile: *intrp.UserFunction.call /Users/cpcallen/src/CodeCity/server/interpreter.js:4782:47
65 2.6% LazyCompile: *Interpreter.getBoundNames_ /Users/cpcallen/src/CodeCity/server/interpreter.js:2907:48
62 2.5% LazyCompile: *stepFuncs_.CallExpression /Users/cpcallen/src/CodeCity/server/interpreter.js:6039:40
我想知道它是否可能实际上是垃圾收集器,但是使用
--trace-gc
显示GC占用的总运行时间少于10%。我如何弄清楚这个C ++函数在做什么?
最佳答案
查找DispatcherImpl
并不难:https://github.com/nodejs/node/search?q=dispatcherimpl&unscoped_q=dispatcherimpl直接导致https://github.com/nodejs/node/blob/5aaa7fee2e4a075d9123b885f9e8cda3de2a780a/tools/inspector_protocol/templates/TypeBuilder_cpp.template#L218。但这可能并不是您真正想要的...--prof
系统中存在一段时间的错误,其中C ++滴答声将归因于错误的功能-看来您可能正在遇到该错误。它已经fixed in V8 recently,但是该修复尚未发布到Node版本中。
解决方法是,在Linux上,您可以使用perf
来配置C ++代码[1],同时仍将--prof
用于JavaScript; JavaScript刻度以及C ++ / JavaScript发行版在--prof
的输出中应该可靠地正确。在其他平台上,应该有等效的通用配置技术。
[1]有关详细信息,请阅读手册页。我通常使用类似:
perf record -e cycles -F 10000 <executable and arguments>
perf report -M intel