内存分析
内存分析使您能够持续了解基于Substrate的客户端的内存分配及区块链应用行为状况。 它能识别被调用的方法所使用的内存是如何分配的,以及分配了多少内存对象给它。 此外,内存分析可用于分析内存泄漏,确定发生内存消耗的位置,定义临时内存分配以及调查应用程序内过多内存碎片的原因。 在本地运行Substrate时,它还会考虑分析runtime的内存使用状况。
了解模式
安装内存分析器
我们建议使用koute内存分析器。 使用前提是您已全局安装了rust稳定版、GCC和yarn这三个工具。
- 克隆代码仓库
- 编译克隆下来的库及命令行界面
git clone https://github.com/koute/memory-profiler
cd memory-profiler
cargo build --release -p memory-profiler # builds the library
cargo build --release -p memory-profiler-cli # builds the cli
在Substrate上使用分析器
首先,在终端中以 release 模式编译客户端(cargo build --release
)。 命令完成后,用预加载的内存分析器运行编译好的二进制文件。 此命令假定memory-profiler
目录位于Substrate目录旁边,并且只有在我们正确放置且调用该目录时才会生效:
LD_PRELOAD=../memory-profiler/target/release/libmemory_profiler.so ./target/release/substrate
您可以照常往Substrate传递命令行参数,并通过环境变量来配置内存分析器。
这将在您定义的目录中创建一个 .dat
文件,并在此文件中维护相关数据以进行分析。 此外,您也通过 web ui 来使用内存分析器服务器执行相同的操作。 要执行此操作,请将内存分析器放置在如下目录中:
../memory-profiler/target/release/memory-profiler-cli server *.dat
该命令将会启动分析功能。 在标准硬件上,分析 1 GB 的数据大约需要一分钟。 Substrate在正常运行的情况下会产生约1.6Gb /小时的runtime运行数据,而在初始编译期间则会产生更多。 一旦runtime成功编译,它将生成一个URL。 这就创建了一种可视化方法来检查数据 (去重的警告可以忽略):
[2020-05-06T08:57:09Z WARN cli_core::loader] Duplicate allocation of 0x00007F58BC20CA90; old backtrace = BacktraceId(21363), new backtrace = BacktraceId(19194)
[2020-05-06T08:57:09Z WARN cli_core::loader] Duplicate allocation of 0x00007F5864230040; old backtrace = BacktraceId(21321), new backtrace = BacktraceId(21321)
[2020-05-06T08:57:09Z WARN cli_core::loader] Duplicate allocation of 0x00007F5864202D70; old backtrace = BacktraceId(21322), new backtrace = BacktraceId(21322)
[2020-05-06T08:59:20Z INFO cli_core::loader] Loaded data in 315s 820
[2020-05-06T08:59:20Z INFO actix_server::builder] Starting 8 workers
[2020-05-06T08:59:20Z INFO actix_server::builder] Starting server on 127.0.0.1:8080
现在,打开浏览器并输入URL(此处为http://localhost:8080/
),然后选择需要调查的会话。 这会出现一个图表,如果分析器正在解析大量数据,则可能需要几分钟的时间来加载。 同时,Substrate跟踪的数据体积将会迅速膨胀,因此针对特定runtime调用所进行的长时间或者深度审查的数据获取,有时候会变得非常困难。
通过在顶部列出的使用REST API链接,您还可以下载其他版本的数据并使用辅助工具进行分析。
Heaptrack
可以使用heaptrack文件和heaptrack GUI来调查特定的函数调用和疑似内存泄露的堆栈轨迹。
提示和技巧
当分析器生成大量日志时,尤其是在Substrate已运行了一段时间的情况下,分析器本身可能会在此过程中耗尽内存并产生分段错误。 为了避免这种情况,请使用 USR1
-Signal来控制内存分析器以创建较小的日志。 无论何时发送此调用,它都会重新启动并创建一个新的日志文件。此外,将数据跟踪分割为30分钟的块(每个块大约800MB)的一种更简单的方法是使用 watch
: PID=12345 watch -n 1800 'kill -USR1 $PID && sleep 1 && kill -USR1 $PID'
。
已知问题
- 当使用
--wasm-execution compiled
命令运行substrate时,内存分析器会发生核心转储(core dumps)。 - 点击
flamegraph
会使服务器崩溃。