监控用户空间应用程序的 CPU 使用率
有几种 Linux 实用程序,如 top 和 htop,可以用来监控 CPU 使用情况。
Top
Top 是一个工具,用于检查应用程序的 CPU 利用率并显示整体 CPU 使用情况。在八核平台上,任务可以将 CPU 利用率从 0% 消耗到 800%。
要设置终端环境以运行 top,请运行以下命令:
export TERM=xterm
top
下图显示了命令的输出中的 CPU 利用率:
Htop
htop 显示每个进程的每核 CPU 使用率和整体 CPU 使用率。要在构建上编译 htop,请参阅编译性能工具。
要为 htop 设置终端环境,请运行以下命令:
export TERM=xterm
htop
下图显示了命令的输出中的每核 CPU 使用率:
Trace Compass 中的 CPU 使用率
1,打开 Trace Compass 工具并加载跟踪数据。
2,右键点击跟踪,然后选择选择跟踪类型 > Ftrace 格式 > 原始文本 Ftrace,如下所示:
3,右键点击原始文本 Ftrace 并选择打开。
4,双击 CPU 使用率以查看系统范围内的 CPU 使用率。在左侧面板中选择一个任务,以检查每个任务的 CPU 使用率,如下所示:
监控用户空间应用程序的内存消耗
您可以检查各种进程的内存分配和内存使用情况。
要检查一个进程的内存消耗,请运行以下命令:
cat /proc/<pid>/smaps_rollup
下图显示了该命令的输出:
Procrank
Procrank 是一个显示每个进程内存消耗的工具。默认情况下,它显示以下大小的内存集:
- Vss:虚拟内存集大小
- Rss:常驻内存集大小
- Pss:比例集大小
- Uss:唯一集大小
Pss 被认为是进程的实际内存消耗量。
在设备上从源代码构建 Procrank
- 在主机上:
使用 git clone
从 https://github.com/cglmcu/procrank 克隆代码。
使用 SCP 或类似的工具将 Procrank 文件从主机传输到设备。以下是示例命令:
mount -o rw,remount /
scp procrank root@10.92.162.185:/home/root
注意
确保在该命令中指定目标 IP 地址。
- 在设备上:
进入 SSH shell 并运行以下命令:
cd /home/root/procrank
aarch64-qcom-linux-gcc *.c -I. -o procrank
cp procrank /usr/bin/
- Procrank 命令示例:
1,要查看每个进程分配的匿名内存,请运行以下命令:
procrank -C
2,要显示每个进程分配的文件缓存内存,请运行以下命令:
procrank -c
3,要查看每个进程分配的匿名和文件缓存内存,请运行以下命令:
procrank
4,下图显示了 procrank -C 命令的示例输出:
检查应用程序的每周期指令数
可以使用 perf 实用工具计算应用程序的每周期指令数(IPC),该工具利用硬件性能计数器。
要编译 perf 实用工具,请参见编译性能工具。
要计算 IPC,请运行以下命令:
setenforce 0
perf stat -e cycles,instructions sleep 5
下图显示了命令的示例输出:
- 如果 IPC 小于 1.0,则可能是内存停滞。在这种情况下,软件调整策略,如减少内存 I/O 工作负载,可以帮助提高性能。
- 如果 IPC 大于 1.0,则可能是指令受限。在这种情况下,通过消除不必要的工作和缓存操作来减少代码执行,可以帮助提高性能。
检查消耗最多 CPU 的代码部分
perf 实用工具可以生成火焰图,帮助可视化线程的调用栈和 CPU 使用情况,包括在 CPU 上运行的所有函数。
要生成火焰图,请按照以下步骤操作:
- 在设备上:
1,收集日志以生成火焰图。要使用 perf 实用工具收集日志,请运行以下命令:
setenforce 0
perf record -g -o /tmp/perf.data -p <进程 pid> sleep 5
cd /tmp
perf script > /tmp/perf.script
2,使用 SCP 或类似的工具运行以下命令,将 perf.script 从目标传输到主机。以下是一个示例命令:
scp -r root@10.92.162.185:/tmp/perf.script /local/mnt/workspace/logs
注意
确保在此命令中指定目标 IP 地址。
- 在主机上:
1,使用 git clone
从 https://github.com/brendangregg/FlameGraph.git 下载火焰图工具。
确保主机上安装了 Perl。
perl stackcollapse-perf.pl perf.script > out.folded
perl out.folded > perf.svg
2,在浏览器中打开 SVG 文件,查看 CPU 使用情况的火焰图:
检查用户空间应用程序代码中函数消耗的内存
Valgrind 是一个开源工具,它提供了一个名为 massif 的实用程序,有助于分析程序中每个函数消耗的内存。当你尝试优化代码或识别内存泄漏时,这可能特别有用。
以下是内存分配的示例代码:
#include <stdlib.h>
void g(void) {
malloc(4000);
}
void f(void) {
malloc(2000);
g();
}
int main(void) {
int i;
int* a[10];
for (i = 0; i < 10; i++) {
a[i] = malloc(1000);
}
f();
g();
for (i = 0; i < 10; i++) {
free(a[i]);
}
return 0;
}
以下是示例代码的输出:
需要 gcc 工具在设备上编译测试代码
$ aarch64-qcom-linux-gcc test.c -o test
运行 Valgrind
$ valgrind --tool=massif ./test
查看输出文件 massif.out.1587
的内容:
Require gcc tool to compile test code on device
$ aarch64-qcom-linux-gcc test.c -o test
Run Valgrind
$ valgrind --tool=massif ./test
cat massif.out.1587
…
n3: 20000 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
n0: 10000 0x10882B: main (in /home/root/valgrind/test)
n2: 8000 0x1087E7: g (in /home/root/valgrind/test)
n1: 4000 0x108807: f (in /home/root/valgrind/test)
n0: 4000 0x10885B: main (in /home/root/valgrind/test)
n0: 4000 0x10885F: main (in /home/root/valgrind/test)
n1: 2000 0x108803: f (in /home/root/valgrind/test)
n0: 2000 0x10885B: main (in /home/root/valgrind/test)
有关 Valgrind 的更多信息,请访问 https://valgrind.org/docs/manual/ms-manual.html。
在用户空间应用程序中检测内存泄漏
要在一个进程内检测内存泄漏,您可以使用一个名为 Valgrind 的工具,并启用泄漏检查功能。
以下是一段示例代码,其中分配了内存但没有释放:
#include <stdlib.h>
void do_alloc() {
int *x = malloc(10 * sizeof(int)); /* 这里模拟一个内存泄漏 */
x[10] = 0; /* 这里写入无效的内存地址 */
}
int main() {
do_alloc();
return 0;
}
以下是示例代码的输出:
$ valgrind --leak-check=yes ./test
==1512== Memcheck, a memory error detector
==1512== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1512== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==1512== Command: ./test
==1512==
==1512== Invalid write of size 4
==1512== at 0x1087B4: do_alloc (in /home/root/valgrind/test)
==1512== by 0x1087CF: main (in /home/root/valgrind/test)
==1512== Address 0x4a36068 is 0 bytes after a block of size 40 alloc'd
==1512== at 0x486551C: malloc (vg_replace_malloc.c:381)
==1512== by 0x1087A7: do_alloc (in /home/root/valgrind/test)
==1512== by 0x1087CF: main (in /home/root/valgrind/test)
==1512==
==1512==
==1512== HEAP SUMMARY:
==1512== in use at exit: 40 bytes in 1 blocks
==1512== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==1512==
==1512== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1512== at 0x486551C: malloc (vg_replace_malloc.c:381)
==1512== by 0x1087A7: do_alloc (in /home/root/valgrind/test)
==1512== by 0x1087CF: main (in /home/root/valgrind/test)