仓颉性能分析工具使用指南
功能简介
cjprof
(Cangjie Profile)是仓颉语言的性能分析工具,支持以下功能:
-
对仓颉语言程序进行 CPU 热点函数采样,导出采样数据。
-
对热点函数采样数据进行分析,生成 CPU 热点函数统计报告或火焰图。
-
导出仓颉语言应用程序堆内存,并对其进行分析生成分析报告。
目前 cjprof
仅支持 linux 系统。
使用说明
通过 cjprof --help
即可查看命令使用方法。支持 record
,report
和 heap
子命令,分别用于采集 CPU 热点函数信息, 生成 CPU 热点函数报告(包含火焰图)和导出与分析堆内存。
cjprof --help
Usage: cjprof [--help] COMMAND [ARGS]
The supported commands are:
heap Dump heap into a dump file or analyze the heap dump file
record Run a command and record its profile data into data file
report Read profile data file (created by cjprof record) and display the profile
注意,由于 cjprof record
依赖系统的 perf 权限,因此使用需要满足以下两个条件之一:
-
使用 root 用户或 sudo 权限执行。
-
系统的
perf_event_paranoid
参数(通过/proc/sys/kernel/perf_event_paranoid
文件配置)配置为 -1 。
否则可能会报权限不足的问题。
采集 CPU 热点函数信息
命令
cjprof record
格式
cjprof record [<options>] [<command>]
cjprof record [<options>] -- <command> [<options>]
选项
-f, --freq <freq>
指定采样频率,单位为赫兹(Hz),即每秒采样次数,默认为 1000Hz,当指定为 max 或超过系统支持的最大频率时,取系统支持的最大频率。
-o, --output <file>
指定采样结束后生成的采样数据文件名,默认为 cjprof.data
。
-p, --pid <pid>
指定被采样应用程序的进程 ID,当指定 <command>
新启动应用程序进行采样时,该选项会被忽略。
示例
- 采样正在运行的应用程序。
cjprof record -f 10000 -p 12345 -o sample.data
说明:以 10000Hz 的采样频率对正在运行的应用程序(进程号为 12345)进行采样,采样结束后将采样数据生成在当前路径下名为 sample.data
的文件中。
- 新启动应用程序并对其进行采样。
cjprof record -f max -- ./test arg1 arg2
说明:执行当前路径下的 test
应用程序,参数为 arg1 arg2
,并以系统支持的最大采样频率对其进行采样,采样结束后将采样数据生成在当前路径下名为 cjprof.data
(默认文件名)的文件中。
说明
- 开始采样后,只有被采样程序退出后才会结束采样,如果需要提前结束采样,可以在采样过程中通过按
Ctrl+C
主动停止采样。
生成 CPU 热点函数报告
命令
cjprof report
格式
cjprof report [<options>]
选项
-F, --flame-graph
生成 CPU 热点函数火焰图,而非默认的文本报告。
-i, --input <file>
采样数据文件名,默认为 cjprof.data
。
-o, --output <file>
生成的 CPU 热点函数火焰图文件名,默认为 FlameGraph.svg
,仅当生成火焰图时才有效。
示例
- 生成默认的 CPU 热点函数文本报告。
cjprof report -i sample.data
说明:分析 sample.data
中的采样数据,生成 CPU 热点函数文本报告。
- 生成 CPU 热点函数火焰图。
cjprof report -F -o test.svg
说明:分析 cjprof.data
(默认文件)中的采样数据,生成名为 test.svg
的 CPU 热点函数火焰图。
说明
-
文本形式的报告包含函数采样总占比(包含子函数)、函数采样占比(自身)以及函数名(如果没有对应的符号信息则显示为地址)三部分,报告结果以函数采样总占比降序排列。
-
火焰图中的横轴代表采样占比大小,越宽表示采样占比越大,即运行时间越长,纵轴表示调用栈,父函数在下,子函数在上。
导出和分析堆内存
命令
cjprof heap
格式
cjprof heap [<options>]
选项
-D, --depth <depth>
指定对象的引用/被引用关系最大展示深度,默认为 10 层,仅在指定了 --show-reference
时才能生效。
-d, --dump <pid>
导出仓颉应用程序当前时刻的堆内存,pid
为应用程序进程号,当指定为应用程序的子线程号时,同样可导出。
-i, --input <file>
指定进行分析的堆内存数据文件名,默认为 cjprof.data
。
-o, --output <file>
指定导出的堆内存数据文件名,默认为 cjprof.data
。
--show-reference[=<objnames>]
分析报告中展示对象的引用关系,objnames
为需要展示的对象名,多个对象使用 ;
隔开,不指定时默认展示所有对象。
--incoming-reference
展示对象的被引用关系,而非引用关系,需要与 --show-reference
配合使用。
-t, --show-thread
分析报告中展示仓颉线程栈,以及在栈中引用的对象。
-V, --verbose
维测选项,解析堆内存数据文件时打印解析日志。
示例
- 导出堆内存数据。
cjprof heap -d 12345 -o heap.data
说明:将正在运行的应用程序(进程号为 12345)当前时刻的堆内存导出到当前路径下名为 heap.data
的文件中。
注意,导出堆内存时会向进程发送 SIG_USR1
信号,在不确定目标进程是否为仓颉应用程序时,需要谨慎操作,否则可能会给目标进程误发送信号导致非预期错误。
- 分析堆内存数据,展示对象信息。
cjprof heap -i ~/heap.data
说明:解析并分析 ~
目录下名为 heap.data
的堆内存数据文件,展示堆中各激活对象的对象类型名、实例个数、浅堆大小和深堆大小。效果如下:
Object Type Objects Shallow Heap Retained Heap
==================== ============= ============= =============
AAA 1 80 400
BBB 4 32 196
CCC 2 16 32
- 分析堆内存数据,展示仓颉线程栈及对象引用。
cjprof heap --show-thread
说明:解析并分析当前目录下名为 cjprof.data
(默认文件)的堆内存数据文件,展示堆中各激活对象的对象类型名、实例个数、浅堆大小和深堆大小,以及仓颉线程栈与栈中引用的对象。效果如下:
Object Type Objects Shallow Heap Retained Heap
==================== ============= ============= =============
AAA 1 80 400
BBB 4 32 196
CCC 2 16 32
Object/Stack Frame Shallow Heap Retained Heap
=================================== ============= =============
thread0
at Func2() (/home/test/test.cj:10)
<local> AAA @ 0x7f1234567800 80 400
at Func1() (/home/test/test.cj:20)
<local> CCC @ 0x7f12345678c0 16 16
at main (/home/test/test.cj:30)
- 分析堆内存数据,展示仓颉线程栈及对象的引用关系。
cjprof heap --show-reference="default::Dirived;std/core::ArrayIterator<Int32>"
说明:解析并分析当前目录下名为 cjprof.data
(默认文件)的堆内存数据文件,展示堆中各激活对象的对象类型名、实例个数、浅堆大小和深堆大小,以及 default::Dirived
和 std/core::ArrayIterator<Int32>
对象的引用关系。效果如下:
Object Type Objects Shallow Heap Retained Heap
==================== ============= ============= =============
AAA 1 80 400
BBB 4 128 196
CCC 2 32 32
Objects with outgoing references:
Object Type Shallow Heap Retained Heap
=================================== ============= =============
AAA @ 0x7f1234567800 80 400
BBB @ 0x7f1234567880 32 48
CCC @ 0x7f12345678c0 16 16
CCC @ 0x7f12345678e0 16 16
- 分析堆内存数据,展示仓颉线程栈及对象的被引用关系。
cjprof heap --show-reference="RawArray<std/core::String>[]" --incoming-reference
说明:解析并分析当前目录下名为 cjprof.data
(默认文件)的堆内存数据文件,展示堆中各激活对象的对象类型名、实例个数、浅堆大小和深堆大小,以及 RawArray<std/core::String>[]
对象的被引用关系。效果如下:
Object Type Objects Shallow Heap Retained Heap
==================== ============= ============= =============
AAA 1 80 400
BBB 4 128 196
CCC 2 32 32
Objects with incoming references:
Object Type Shallow Heap Retained Heap
=================================== ============= =============
CCC @ 0x7f12345678c0 16 16
BBB @ 0x7f1234567880 32 48
AAA @ 0x7f1234567800 80 400
CCC @ 0x7f12345678e0 16 16
AAA @ 0x7f1234567800 80 400
说明
-
对象类型名使用
RawArray<Byte>[]
,RawArray<Half>[]
,RawArray<Word>[]
和RawArray<DWord>[]
分别表示 1 字节、2 字节、4 字节和 8 字节大小的基础数据类型原始数组。 -
浅堆是指对象自身所占用的堆内存大小,深堆是指对象被垃圾回收后,可以被释放的所有对象(即仅能通过该对象直接或间接引用到的对象)的浅堆大小之和。
-
当对象的引用关系层级超出最大展示深度后,或是存在循环引用出现重复对象后,会使用
...
来省略后续引用。