Linux lsmem命令

lsmem 是一个用于显示系统内存块信息的命令,它可以列出系统中的内存区域、内存块大小、范围和状态,帮助用户了解系统的内存布局和物理内存分配情况。

命令简介

lsmemutil-linux 软件包的一部分,它通过读取 /sys/devices/system/memory/ 目录下的信息来显示系统的内存块信息。这对于理解系统内存布局、诊断内存相关问题和规划内存分配非常有用。

主要功能
  • 显示系统内存块布局
  • 显示每个内存块的物理地址范围
  • 显示内存块大小和状态
  • 显示内存块所属的内存节点(NUMA)
  • 帮助识别可热插拔的内存区域
  • 显示内存块的removable状态
注意事项
  • 需要适当权限查看完整信息
  • 显示的是物理内存块信息,不是虚拟内存
  • 不同架构的系统输出可能不同
  • 某些信息可能需要内核支持
  • 输出信息取决于系统配置和硬件

安装方法

lsmem 通常包含在 util-linux 包中,大多数Linux发行版已预装:

Ubuntu/Debian
# 如果未安装,可以使用以下命令
sudo apt update
sudo apt install util-linux
CentOS/RHEL
# 通常已预装,如需重新安装
sudo yum install util-linux
检查是否已安装: 运行 which lsmemlsmem --version 2>/dev/null || echo "未安装"

语法格式

lsmem [选项]
参数说明:
  • 选项:可选参数,用于控制输出格式和内容
  • 如果不指定选项,将显示所有内存块的摘要信息

常用参数

参数 说明
-h--help 显示帮助信息
-V--version 显示版本信息
-a--all 显示所有内存块的详细信息
-b--bytes 以字节为单位显示大小
-k--kilo 以千字节为单位显示大小
-m--mega 以兆字节为单位显示大小
-g--giga 以千兆字节为单位显示大小
-H--human 以人类可读的格式显示大小
-n--noheadings 不显示标题行
-o--output <字段列表> 指定要显示的字段
-p--pairs 以key=value格式输出
-r--raw 原始格式输出,无对齐
-S--split <列表> 按指定列拆分输出
-s--summary 仅显示摘要信息
-y--sysroot <目录> 使用指定目录作为系统根目录
--output-all 输出所有可用字段
--list 使用列表格式输出(默认)
输出字段说明

lsmem 可以显示多个字段,以下是常用字段的说明:

字段 说明
RANGE 内存块的物理地址范围
SIZE 内存块的大小
STATE 内存块状态(online, offline)
REMOVABLE 内存块是否可热移除
BLOCK 内存块标识符
NODE 内存块所属的NUMA节点
ZONE 内存块所属的内存区域
OFFLINE 内存块是否离线
ONLINE 内存块是否在线
MAX 最大可在线内存块数量
MIN 最小可在线内存块数量

使用示例

示例1:基本使用

显示内存块摘要信息:

lsmem

输出示例:

RANGE                                 SIZE  STATE REMOVABLE BLOCK
0x0000000000000000-0x00000000bfffffff   3G online       yes  0-23
0x0000000100000000-0x000000027fffffff   6G online       yes 32-87

Memory block size:       128M
Total online memory:       9G
Total offline memory:      0B
示例2:显示详细信息

显示所有内存块的详细信息:

lsmem -a

以人类可读格式显示:

lsmem -H

以字节为单位显示:

lsmem -b

以兆字节为单位显示:

lsmem -m
示例3:自定义输出格式

只显示特定字段:

lsmem -o RANGE,SIZE,STATE

以key=value格式输出:

lsmem -p

输出示例:

RANGE="0x0000000000000000-0x00000000bfffffff" SIZE="3G" STATE="online" REMOVABLE="yes" BLOCK="0-23"
RANGE="0x0000000100000000-0x000000027fffffff" SIZE="6G" STATE="online" REMOVABLE="yes" BLOCK="32-87"

不显示标题行:

lsmem -n
示例4:过滤和统计

只显示在线内存块:

lsmem -a | grep "online"

只显示可热移除的内存块:

lsmem -a | grep "yes"

统计在线内存总量:

lsmem -s | grep "Total online"

计算内存块数量:

lsmem -n | wc -l
示例5:脚本中使用

获取内存块信息并解析:

#!/bin/bash
echo "系统内存块分析报告"
echo "===================="
echo "生成时间: $(date)"
echo ""

# 获取内存块大小
BLOCK_SIZE=$(lsmem | grep "Memory block size:" | awk '{print $4}')
echo "内存块大小: $BLOCK_SIZE"

# 获取在线内存总量
ONLINE_MEM=$(lsmem -s | grep "Total online memory:" | awk '{print $4 $5}')
echo "在线内存总量: $ONLINE_MEM"

# 获取离线内存总量
OFFLINE_MEM=$(lsmem -s | grep "Total offline memory:" | awk '{print $4 $5}')
echo "离线内存总量: $OFFLINE_MEM"

# 统计内存块数量
BLOCK_COUNT=$(lsmem -n | wc -l)
echo "内存块数量: $BLOCK_COUNT"

# 统计可热移除的内存块数量
REMOVABLE_COUNT=$(lsmem -a | grep "yes" | wc -l)
echo "可热移除的内存块: $REMOVABLE_COUNT"
示例6:高级分析和监控

监控内存块状态变化:

#!/bin/bash
echo "开始监控内存块状态变化..."
OLD_STATE=$(lsmem -o STATE | sort | md5sum)

while true; do
    NEW_STATE=$(lsmem -o STATE | sort | md5sum)
    if [ "$OLD_STATE" != "$NEW_STATE" ]; then
        echo "$(date): 内存块状态发生变化"
        echo "当前状态:"
        lsmem -o RANGE,STATE | grep -v "online"
        OLD_STATE=$NEW_STATE
    fi
    sleep 5
done

分析NUMA节点内存分布:

#!/bin/bash
echo "NUMA节点内存分布分析"
echo "====================="

# 获取所有NUMA节点
NODES=$(lsmem -o NODE | grep -v "NODE" | sort -u)

for node in $NODES; do
    echo "节点 $node:"

    # 计算该节点的内存总量
    NODE_MEM=$(lsmem -o NODE,SIZE -n | awk -v node="$node" '$1 == node {print $2}' | \
        awk '{sum += $1} END {print sum}')

    # 统计该节点的内存块数量
    NODE_COUNT=$(lsmem -o NODE -n | grep -c "^$node$")

    echo "  内存块数量: $NODE_COUNT"
    echo "  内存总量: ${NODE_MEM}G"

    # 检查该节点是否有可热移除的内存
    REMOVABLE=$(lsmem -o NODE,REMOVABLE -n | awk -v node="$node" '$1 == node && $2 == "yes" {count++} END {print count}')
    echo "  可热移除的内存块: $REMOVABLE"

    echo ""
done

实用技巧

信息提取
  • 使用grep过滤特定状态的内存块
  • 使用awk提取和计算特定字段
  • 使用sortuniq分析内存分布
  • 结合numactl分析NUMA架构
故障排查
  • 检查离线内存块是否影响系统性能
  • 确认可热移除内存是否正常
  • 分析内存碎片化情况
  • 监控内存块状态变化
脚本示例:内存健康检查
#!/bin/bash
# 内存健康检查脚本

echo "内存健康检查报告"
echo "================"
echo "检查时间: $(date)"
echo ""

# 检查是否有离线内存块
OFFLINE_COUNT=$(lsmem -o STATE -n | grep -c "offline")
if [ $OFFLINE_COUNT -gt 0 ]; then
    echo "⚠️  警告: 发现 $OFFLINE_COUNT 个离线内存块"
    echo "离线内存块详情:"
    lsmem -o RANGE,SIZE,STATE | grep "offline"
else
    echo "✅ 所有内存块都在线"
fi

echo ""

# 检查内存块大小是否一致
BLOCK_SIZES=$(lsmem -o SIZE -n | sort -u | wc -l)
if [ $BLOCK_SIZES -gt 1 ]; then
    echo "⚠️  警告: 发现多种内存块大小"
    echo "内存块大小分布:"
    lsmem -o SIZE -n | sort | uniq -c
else
    echo "✅ 所有内存块大小一致"
fi

echo ""

# 检查可热移除内存
TOTAL_BLOCKS=$(lsmem -n | wc -l)
REMOVABLE_BLOCKS=$(lsmem -o REMOVABLE -n | grep -c "yes")
if [ $REMOVABLE_BLOCKS -lt $TOTAL_BLOCKS ]; then
    echo "⚠️  注意: 部分内存块不可热移除"
    echo "可热移除比例: $REMOVABLE_BLOCKS/$TOTAL_BLOCKS"
else
    echo "✅ 所有内存块都可热移除"
fi

echo ""
echo "检查完成"
服务器管理中的应用

在服务器管理中,lsmem可以帮助:

  1. 内存热插拔规划:识别可热移除的内存块
  2. 故障诊断:检查离线内存块和硬件故障
  3. 性能优化:分析NUMA节点内存分布
  4. 容量规划:了解实际物理内存布局
  5. 虚拟化环境:规划虚拟机内存分配
内存相关命令
  • free - 显示内存使用情况
  • vmstat - 显示虚拟内存统计
  • top - 显示进程和内存使用
  • numastat - 显示NUMA内存统计
  • dmidecode - 显示DMI内存信息
系统信息命令
  • lscpu - 显示CPU信息
  • lsblk - 显示块设备信息
  • lspci - 显示PCI设备信息
  • lsusb - 显示USB设备信息
  • uname - 显示系统信息
命令比较

lsmemfree 的主要区别:

特性 lsmem free
关注点 物理内存块布局和状态 内存使用情况和统计
信息类型 物理内存区域、范围、状态 已用内存、可用内存、缓存、缓冲区
数据源 /sys/devices/system/memory/ /proc/meminfo
使用场景 硬件诊断、内存规划、热插拔管理 性能监控、系统调优、资源管理
输出格式 内存块列表、范围、状态 内存总量、使用量、空闲量

建议:

  • 查看物理内存布局和状态使用 lsmem
  • 查看内存使用情况和性能使用 freevmstat
  • 诊断内存硬件问题结合使用 lsmemdmidecode
  • 在NUMA系统中结合使用 lsmemnumactl
注意事项
  • lsmem显示的是物理内存块信息,不是虚拟内存或进程内存使用情况
  • 内存块状态可能因系统配置和硬件限制而不同
  • 热移除内存操作需要硬件和内核支持
  • 某些内存块可能因硬件保留或BIOS设置而不可用
  • 不同架构(x86, ARM, PowerPC)的内存布局可能不同
  • 在生产环境中操作内存热插拔前,应在测试环境中验证