linux smem命令

smem命令 是一个强大的内存使用报告工具,可以显示系统的内存使用情况,包括实际使用内存(RSS)、比例设置大小(PSS)、独占内存(USS)等。它能提供更准确的内存使用统计,特别适用于分析共享内存。

命令格式

smem [选项] [筛选条件]

常用选项

选项 说明
-t, --totals 显示总计行
-c, --columns 指定显示的列
-s, --sort 按指定列排序
-r, --reverse 反向排序
-p, --percent 显示百分比
-u, --users 按用户显示汇总
-w, --system 显示系统汇总
-P, --processfilter 筛选进程(支持正则)
-U, --userfilter 筛选用户(支持正则)
-m, --mappings 显示内存映射详情
-k, --abbreviate 以KB为单位(默认)
-m, --megabytes 以MB为单位
-g, --gigabytes 以GB为单位
-H, --no-header 不显示标题行
-n, --numeric 显示数字用户ID
-R, --real 显示真实内存使用(考虑共享)
-S, --swap 显示交换使用情况
-a, --autocomplete 自动补全列名
-o, --output 输出到文件
-f, --format 指定输出格式(csv, json等)

内存指标说明

RSS
常驻内存大小

进程实际占用的物理内存(包括共享库)

问题:重复计算共享内存

PSS
比例设置大小

共享内存按进程数比例分配后的内存

优点:更准确反映内存使用

USS
独占内存大小

进程独占的、不共享的内存

用途:杀死进程可释放的内存

详细对比

指标 全称 说明 特点
RSS Resident Set Size 进程实际占用的物理内存 包含共享内存,可能重复计算
PSS Proportional Set Size 共享内存按比例分配后的内存 最准确的内存使用指标
USS Unique Set Size 进程独占的内存 杀死进程可释放的内存
VSS Virtual Set Size 虚拟内存大小 进程可访问的总内存空间
Swap Swap Usage 交换空间使用量 被换出到磁盘的内存

使用实例

1. 显示所有进程的内存使用(默认)
smem
2. 显示总计和百分比
smem -t -p
3. 按PSS排序(降序)
smem -s pss -r
4. 按用户显示内存使用汇总
smem -u
5. 显示系统内存汇总
smem -w
6. 指定显示的列
# 显示指定列
smem -c "name user pss rss uss"

# 显示所有可用列
smem -c "pid name user command pss rss uss vss swap library"
7. 筛选特定进程
# 筛选包含"nginx"的进程
smem -P nginx

# 筛选特定用户的进程
smem -U root

# 组合筛选
smem -P "nginx|apache" -U www-data
8. 以MB为单位显示
smem -m
9. 显示内存映射详情
smem -m -P firefox
10. 显示交换使用情况
smem -S
11. 输出到CSV文件
smem -t -p -c "name user pss rss" -f csv -o memory_report.csv
12. 输出到JSON格式
smem -f json -o memory_report.json
13. 监控特定进程的内存变化
# 每2秒刷新一次,监控nginx进程
watch -n 2 'smem -P nginx -t'
14. 显示图形化报告(需要图形界面)
# 显示条形图
smem --bar name -c "pss rss"

# 显示饼图
smem --pie name -s rss

实际输出示例

示例1:基本输出
$ smem
  PID User     Command                         Swap      USS      PSS      RSS
 1234 alice    /usr/lib/firefox/firefox        8.4M   245.6M   265.3M   310.2M
 5678 bob      /usr/bin/gnome-shell            4.2M   120.3M   135.6M   180.5M
 9012 root     /usr/sbin/nginx -g daemon       0.0M    15.3M    18.7M    25.6M
23456 mysql    /usr/sbin/mysqld                2.1M    85.4M    92.3M   120.8M
示例2:显示总计和百分比
$ smem -t -p
  PID User     Command                         Swap      USS      PSS      RSS
 1234 alice    /usr/lib/firefox/firefox        8.4M   245.6M   265.3M   310.2M
 5678 bob      /usr/bin/gnome-shell            4.2M   120.3M   135.6M   180.5M
 9012 root     /usr/sbin/nginx -g daemon       0.0M    15.3M    18.7M    25.6M
-------------------------------------------------------------------------------
    3 2                                       12.6M   381.2M   419.6M   516.3M
                                                        74.1%    81.6%   100.0%
示例3:按用户汇总
$ smem -u
User     Count     Swap      USS      PSS      RSS
alice        5    25.6M   450.2M   520.3M   610.5M
bob          3    12.8M   230.1M   280.4M   350.2M
root         8     4.2M   180.5M   210.3M   280.6M
-------------------------------------------------------------------------------
            16    42.6M   860.8M  1011.0M  1241.3M
示例4:系统汇总
$ smem -w
Area                           Used      Cache   Noncache
firmware/hardware               0.0M       0.0M       0.0M
kernel image                    0.0M       0.0M       0.0M
kernel dynamic memory        1200.3M     450.2M     750.1M
userspace memory             3450.8M    1200.5M    2250.3M
free memory                  1024.0M    1024.0M       0.0M
-----------------------------------------------------------
                           5675.1M    2674.7M    3000.4M

内存分析场景

内存泄漏检测
  • 监控USS增长趋势
  • 检查共享内存使用
  • 分析缓存占用
  • 定位内存泄漏进程
性能优化
  • 识别内存消耗大户
  • 分析共享库内存占用
  • 优化进程内存配置
  • 调整系统缓存策略
故障排查
  • 内存不足问题分析
  • 交换空间使用分析
  • OOM Killer原因调查
  • 系统卡顿诊断
容量规划
  • 评估内存需求
  • 规划系统升级
  • 容器内存配置
  • 云资源优化

实用命令组合

# 找出PSS最高的10个进程
smem -s pss -r | head -11

# 查看每个用户的内存使用排名
smem -u -s rss -r

# 监控特定进程的内存变化
while true; do
    smem -P nginx -t -m
    sleep 5
done

# 生成内存使用报告
smem -t -p -c "name user pss rss swap" --percentages > /tmp/memory_report.txt

# 分析共享内存占用
smem -m -P java | grep -E "\.so|\.jar"

# 比较不同指标的区别
smem -c "name rss pss uss" -P chrome | tail -5

与相关命令对比

命令 主要功能 内存指标 优点 缺点
smem 详细内存分析 USS, PSS, RSS, Swap 提供准确的内存使用统计 需要额外安装
ps 进程状态查看 RSS, VSZ 系统自带,速度快 不能区分共享内存
top/htop 实时系统监控 RES, VIRT 交互式,实时刷新 内存统计不精确
free 系统内存概览 total, used, free, cache 查看系统整体内存 不能看进程级别
pmap 进程内存映射 详细的内存映射 显示内存区域详情 输出复杂,不易读
注意事项:
  • smem需要root权限才能查看所有进程的完整信息
  • PSS是最准确的内存使用指标,推荐使用PSS进行内存分析
  • USS表示杀死进程可释放的内存大小
  • smem统计可能比top/ps显示的内存使用更小(因为排除了共享内存的重复计算)
  • 在容器环境中,smem可能无法获取完整的系统信息
  • 使用-m选项查看内存映射详情时输出会很庞大

安装smem

smem不是默认安装的,需要手动安装:

# Ubuntu/Debian
sudo apt-get install smem

# CentOS/RHEL/Fedora
sudo yum install smem

# Arch Linux
sudo pacman -S smem

# 从源码编译安装
git clone https://github.com/smemsrc/smem.git
cd smem
sudo python setup.py install

# 验证安装
smem --version

# 安装可选依赖(用于图形输出)
sudo apt-get install python3-matplotlib  # Ubuntu/Debian
sudo yum install python3-matplotlib      # CentOS/RHEL

Python API使用

smem提供了Python API,可以在脚本中使用:

#!/usr/bin/env python3
import smem

# 获取内存统计
stats = smem.SMem()

# 打印所有进程
for proc in stats.processes:
    print(f"PID: {proc.pid}, Name: {proc.name}, PSS: {proc.pss}")

# 按用户汇总
user_stats = stats.users
for user, data in user_stats.items():
    print(f"User: {user}, Count: {data['count']}, PSS: {data['pss']}")

# 获取系统汇总
system_stats = stats.system
print(f"Total RSS: {system_stats['rss']}")
print(f"Total PSS: {system_stats['pss']}")

实际案例:分析内存泄漏

#!/bin/bash
# 内存泄漏监控脚本

LOG_FILE="/var/log/memory_leak.log"
PROCESS_NAME="myapp"

echo "=== 内存泄漏监控开始于 $(date) ===" >> $LOG_FILE

while true; do
    # 获取进程的USS和PSS
    USS=$(smem -P $PROCESS_NAME -c uss -H -n | head -1)
    PSS=$(smem -P $PROCESS_NAME -c pss -H -n | head -1)

    if [ -z "$USS" ]; then
        echo "$(date): 进程 $PROCESS_NAME 未找到" >> $LOG_FILE
    else
        echo "$(date): $PROCESS_NAME - USS: ${USS}KB, PSS: ${PSS}KB" >> $LOG_FILE

        # 如果USS持续增长超过阈值,发出警告
        if [ $USS -gt 1000000 ]; then  # 超过1GB
            echo "$(date): [警告] $PROCESS_NAME 内存使用过高: ${USS}KB" >> $LOG_FILE
            # 可以发送邮件或调用其他告警
        fi
    fi

    # 每小时生成一次报告
    if [ $(date +%M) -eq "00" ]; then
        echo "=== 每小时报告 ===" >> $LOG_FILE
        smem -P $PROCESS_NAME -t -p >> $LOG_FILE
        echo "" >> $LOG_FILE
    fi

    sleep 300  # 5分钟检查一次
done

相关命令

free

显示系统内存使用情况

查看详情
top/htop

实时系统监控

查看详情
pmap

进程内存映射详情

查看详情