每隔5分钟统计一次指定程序的内存使用量,输出到标准输出。
安装 ps_mem
sudo apt install python3-pip
sudo pip3 install ps_mem
shell 脚本
#!/bin/bash
# 定义需要跟踪的程序列表
programs=("front8m_perception_node"
"fisheyes_perception_node"
"decodec"
"foxg_viz_front8m_od_res_node"
"foxg_viz_front8m_resied_img_node"
"foxg_viz_fisheyes_od_res_node"
"foxg_viz_fisheyes_img_node")
while true; do
# 遍历程序列表
for program_name in "${programs[@]}"; do
# 检查程序是否已经启动
if pidof $program_name > /dev/null;then
pid=$(pidof $program_name | sed 's/ /,/g')
# 获取内存使用信息
mem_info=$(ps_mem -p $pid | grep $program_name)
# 提取私有内存、共享内存和已使用内存的值
private_mem=$(echo $mem_info | awk '{print $1}')
shared_mem=$(echo $mem_info | awk '{print $4}')
used_mem=$(echo $mem_info | awk '{print $7}')
prog_name=$(echo $mem_info | awk '{print $9$10}')
else
# 未启动的程序设置内存使用信息为0
private_mem=0
shared_mem=0
used_mem=0
prog_name=$program_name
fi
# 获取当前时间
current_time=$(date +"%Y-%m-%d %H:%M:%S")
# 输出记录
printf "%-19s | Program: %-50s | Private: %-10s | Shared: %-10s | Used: %-10s\n" "$current_time" "$prog_name" "$private_mem" "$shared_mem" "$used_mem"
done
# 等待5分钟
sleep 300
done
几点解释:
- programs=(“prog1” “prog2”) 是需要跟踪的程序列表,可以根据需要修改。
- sed ‘s/ /,/g’ 是为了应对程序启动多个进程的情况。比如程序启动了两个进程,pidof 的输出是 “1234 5678”,而 ps_mem 要求的输入是 “1234,5678”。
配套的可视化数据python脚本
import matplotlib.pyplot as plt
def plot(num_progs: int):
# 存储每个程序的内存使用量
programs = {}
# 读取文本文件
with open('memory_log.txt', 'r') as file:
for i, line in enumerate(file):
# 解析每行的信息
parts = line.strip().split('|')
# time = parts[0].strip().split()[1].strip()[:-3] # 提取小时和分钟部分
time = i // num_progs
program = parts[1].strip().split(':')[1].strip()
private = float(parts[2].strip().split(':')[1].strip())
shared = float(parts[3].strip().split(':')[1].strip())
used = float(parts[4].strip().split(':')[1].strip())
# 添加到程序字典中
if program not in filtered_program:
if program not in programs:
programs[program] = {'time': [], 'private': [], 'shared': [], 'used': []}
programs[program]['time'].append(time)
programs[program]['private'].append(private)
programs[program]['shared'].append(shared)
programs[program]['used'].append(used)
# 创建包含三个子图的网格
fig, axes = plt.subplots(1, 3, figsize=(12, 4))
# 绘制Private内存使用量折线图
ax1 = axes[0]
for program, data in programs.items():
ax1.plot(data['time'], data['private'], label=program)
ax1.set_title('Private Memory Usage')
ax1.set_xlabel('Time')
ax1.set_ylabel('Memory (MB)')
ax1.legend()
# 绘制Shared内存使用量折线图
ax2 = axes[1]
for program, data in programs.items():
ax2.plot(data['time'], data['shared'], label=program)
ax2.set_title('Shared Memory Usage')
ax2.set_xlabel('Time')
ax2.set_ylabel('Memory (MB)')
ax2.legend()
# 绘制Used内存使用量折线图
ax3 = axes[2]
for program, data in programs.items():
ax3.plot(data['time'], data['used'], label=program)
ax3.set_title('Used Memory Usage')
ax3.set_xlabel('Time')
ax3.set_ylabel('Memory (MB)')
ax3.legend()
# 调整子图之间的间距
plt.tight_layout()
# 显示图表
plt.show()
import sys
def main():
num_progs = int(sys.argv[1])
plot(num_progs)
if __name__ == "__main__":
try:
main()
except Exception as e:
print("error: " + str(e))
print("调用示例:")
print("python script.py [num_progs]")