在 Linux 系统中,获取内存信息是一项常见且重要的任务。无论是系统监控、性能调优还是故障排查,都需要准确获取内存使用情况。本文将详细介绍 Linux 中获取内存信息的各种方法,从命令行工具到编程接口,全面覆盖不同场景的需求。
![图片[1]_Linux 内存获取方法详解_知途无界](https://zhituwujie.com/wp-content/uploads/2025/12/d2b5ca33bd20251201102014.png)
1. 文件系统接口
Linux 内核通过虚拟文件系统接口暴露内存信息,这是最直接和权威的数据来源。
1.1 /proc/meminfo – 最全面的内存信息
/proc/meminfo 是获取内存信息最重要的文件,包含了系统内存的详细统计。
# 查看完整的内存信息
cat /proc/meminfo
# 实时监控内存变化(每2秒刷新一次)
watch -n 2 'cat /proc/meminfo | head -20'
关键字段解析:
$ cat /proc/meminfo
MemTotal: 16302048 kB # 总物理内存
MemFree: 2345678 kB # 完全空闲内存
MemAvailable: 8567432 kB # 可用内存(估算可立即分配给进程的内存)
Buffers: 345678 kB # 块设备缓冲区
Cached: 4567890 kB # 页缓存(文件内容缓存)
SwapTotal: 2097148 kB # 交换分区总大小
SwapFree: 2097148 kB # 空闲交换空间
Shmem: 123456 kB # 共享内存(包括tmpfs)
Slab: 567890 kB # Slab分配器使用的内存
Committed_AS: 12345678 kB # 已承诺给进程的内存总量
VmallocUsed: 123456 kB # vmalloc使用的内存
实用脚本示例:
#!/bin/bash
# 获取内存使用摘要
get_memory_info() {
local mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
local mem_free=$(grep MemFree /proc/meminfo | awk '{print $2}')
local mem_available=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
local buffers=$(grep Buffers /proc/meminfo | awk '{print $2}')
local cached=$(grep Cached /proc/meminfo | awk '{print $2}')
local swap_total=$(grep SwapTotal /proc/meminfo | awk '{print $2}')
local swap_free=$(grep SwapFree /proc/meminfo | awk '{print $2}')
local mem_used=$((mem_total - mem_free))
local mem_usage_percent=$((mem_used * 100 / mem_total))
local swap_used=$((swap_total - swap_free))
local swap_usage_percent=0
if [ $swap_total -gt 0 ]; then
swap_usage_percent=$((swap_used * 100 / swap_total))
fi
echo "=== Memory Usage Summary ==="
echo "Total RAM: $((mem_total/1024)) MB"
echo "Used RAM: $((mem_used/1024)) MB ($mem_usage_percent%)"
echo "Available: $((mem_available/1024)) MB"
echo "Buffers/Cache: $(((buffers + cached)/1024)) MB"
echo "Swap Total: $((swap_total/1024)) MB"
echo "Swap Used: $((swap_used/1024)) MB ($swap_usage_percent%)"
echo "==========================="
}
get_memory_info
1.2 /proc//status – 进程内存信息
查看特定进程的内存使用情况:
# 查看当前shell进程的内存信息
cat /proc/$$/status | grep -i mem
# 查看指定PID进程的内存信息
cat /proc/1234/status | grep -i mem
# 查看所有进程的内存信息(按内存使用排序)
ps aux --sort=-%mem | head -10
关键字段:
VmSize: 123456 kB # 虚拟内存大小
VmLck: 0 kB # 锁定的内存大小
VmRSS: 12345 kB # 驻留集大小(实际使用的物理内存)
VmData: 67890 kB # 数据段大小
VmStk: 132 kB # 栈大小
VmExe: 1234 kB # 可执行代码大小
VmLib: 12345 kB # 共享库大小
VmPTE: 456 kB # 页表项大小
1.3 /proc//maps – 进程内存映射
查看进程的内存地址空间分布:
# 查看当前进程的内存映射
cat /proc/$$/maps
# 查看指定进程的内存映射(更详细的格式)
pmap -XX $$ # 当前shell
pmap -XX 1234 # 指定PID
1.4 /sys/devices/system/memory/ – sysfs 接口
sysfs 提供了更结构化的内存信息:
# 查看内存块信息
ls /sys/devices/system/memory/
cat /sys/devices/system/memory/block_size_bytes
# 查看每个内存块的在线状态
cat /sys/devices/system/memory/*/state
# 查看NUMA节点信息
ls /sys/devices/system/node/
numactl --hardware # 更友好的NUMA信息展示
2. 命令行工具
2.1 free – 快速内存概览
# 基本用法
free
free -h # 人类可读格式
free -m # MB为单位
free -g # GB为单位
# 示例输出
$ free -h
total used free shared buff/cache available
Mem: 15Gi 3.2Gi 1.8Gi 345Mi 10Gi 11Gi
Swap: 2.0Gi 0B 2.0Gi
输出字段说明:
- total: 总内存
- used: 已使用内存(不包含buffers/cache)
- free: 完全空闲内存
- shared: 共享内存
- buff/cache: 缓冲区和缓存
- available: 估算的可用内存
2.2 top/htop – 实时进程内存监控
# 使用top
top
# 按内存使用排序:Shift+M
# 显示完整命令行:c
# 退出:q
# 使用htop(需要安装)
htop
# F6 选择排序字段(PERCENT_MEM)
# F5 切换树状视图
2.3 vmstat – 虚拟内存统计
# 基本用法
vmstat
vmstat 2 5 # 每2秒采样,共5次
# 详细内存统计
vmstat -s # 显示内存相关的统计信息
vmstat -a # 显示活跃和非活跃内存
# 示例输出
$ vmstat -s
16302048 K total memory
3291456 K used memory
1234567 K active memory
2345678 K inactive memory
8567432 K free memory
345678 K buffer memory
4567890 K swap cache
2.4 sar – 系统活动报告
# 安装sysstat包(包含sar)
sudo apt install sysstat # Debian/Ubuntu
sudo yum install sysstat # RHEL/CentOS
# 查看内存历史数据
sar -r
sar -r -f /var/log/sa/sa28 # 查看指定日期的数据
# 实时监控
sar -r 2 5 # 每2秒采样,共5次
# 查看内存分页统计
sar -B
2.5 ps – 进程内存快照
# 查看内存使用最高的进程
ps aux --sort=-%mem | head -10
# 自定义输出格式
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -10
# 查看特定用户的进程内存使用
ps -u username --sort=-%mem
# 查看线程内存使用
ps -eLf --sort=-sz
3. 编程接口
3.1 C语言接口
使用 /proc/meminfo
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
unsigned long total;
unsigned long free;
unsigned long available;
unsigned long buffers;
unsigned long cached;
unsigned long swap_total;
unsigned long swap_free;
} memory_info_t;
int parse_meminfo(memory_info_t *mem_info) {
FILE *fp = fopen("/proc/meminfo", "r");
if (!fp) {
perror("Failed to open /proc/meminfo");
return -1;
}
char line[256];
while (fgets(line, sizeof(line), fp)) {
unsigned long value;
char key[64];
if (sscanf(line, "%63[^:]: %lu", key, &value) == 2) {
if (strcmp(key, "MemTotal") == 0) {
mem_info->total = value;
} else if (strcmp(key, "MemFree") == 0) {
mem_info->free = value;
} else if (strcmp(key, "MemAvailable") == 0) {
mem_info->available = value;
} else if (strcmp(key, "Buffers") == 0) {
mem_info->buffers = value;
} else if (strcmp(key, "Cached") == 0) {
mem_info->cached = value;
} else if (strcmp(key, "SwapTotal") == 0) {
mem_info->swap_total = value;
} else if (strcmp(key, "SwapFree") == 0) {
mem_info->swap_free = value;
}
}
}
fclose(fp);
return 0;
}
void print_memory_info(const memory_info_t *mem_info) {
printf("Memory Information:\n");
printf(" Total: %lu kB (%.2f MB)\n",
mem_info->total, mem_info->total / 1024.0);
printf(" Free: %lu kB (%.2f MB)\n",
mem_info->free, mem_info->free / 1024.0);
printf(" Available: %lu kB (%.2f MB)\n",
mem_info->available, mem_info->available / 1024.0);
printf(" Buffers: %lu kB (%.2f MB)\n",
mem_info->buffers, mem_info->buffers / 1024.0);
printf(" Cached: %lu kB (%.2f MB)\n",
mem_info->cached, mem_info->cached / 1024.0);
unsigned long used = mem_info->total - mem_info->free;
double usage_percent = (double)used / mem_info->total * 100;
printf(" Used: %lu kB (%.2f MB) %.1f%%\n",
used, used / 1024.0, usage_percent);
if (mem_info->swap_total > 0) {
unsigned long swap_used = mem_info->swap_total - mem_info->swap_free;
double swap_percent = (double)swap_used / mem_info->swap_total * 100;
printf(" Swap: %lu kB used / %lu kB total (%.1f%%)\n",
swap_used, mem_info->swap_total, swap_percent);
}
}
int main() {
memory_info_t mem_info;
if (parse_meminfo(&mem_info) == 0) {
print_memory_info(&mem_info);
}
return 0;
}
使用 sysinfo 系统调用
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysinfo.h>
void print_sysinfo_memory() {
struct sysinfo info;
if (sysinfo(&info) != 0) {
perror("sysinfo failed");
return;
}
printf("System Information (sysinfo):\n");
printf(" Total RAM: %lu MB\n", info.totalram / 1024 / 1024);
printf(" Free RAM: %lu MB\n", info.freeram / 1024 / 1024);
printf(" Shared RAM: %lu MB\n", info.sharedram / 1024 / 1024);
printf(" Buffer RAM: %lu MB\n", info.bufferram / 1024 / 1024);
printf(" Total Swap: %lu MB\n", info.totalswap / 1024 / 1024);
printf(" Free Swap: %lu MB\n", info.freeswap / 1024 / 1024);
printf(" Number of processes: %d\n", info.procs);
}
int main() {
print_sysinfo_memory();
return 0;
}
3.2 Python 接口
使用 psutil 库(推荐)
import psutil
import datetime
def get_memory_info():
"""获取系统内存信息"""
memory = psutil.virtual_memory()
swap = psutil.swap_memory()
print("=" * 50)
print("Memory Information")
print("=" * 50)
print(f"Total: {memory.total / (1024**3):.2f} GB")
print(f"Available: {memory.available / (1024**3):.2f} GB")
print(f"Used: {memory.used / (1024**3):.2f} GB ({memory.percent}%)")
print(f"Free: {memory.free / (1024**3):.2f} GB")
print(f"Buffers: {memory.buffers / (1024**2):.2f} MB")
print(f"Cached: {memory.cached / (1024**2):.2f} MB")
print()
print(f"Swap Total: {swap.total / (1024**3):.2f} GB")
print(f"Swap Used: {swap.used / (1024**3):.2f} GB ({swap.percent}%)")
print(f"Swap Free: {swap.free / (1024**3):.2f} GB")
def get_process_memory(pid=None):
"""获取进程内存信息"""
if pid is None:
pid = os.getpid()
try:
process = psutil.Process(pid)
mem_info = process.memory_info()
mem_percent = process.memory_percent()
print(f"\nProcess {pid} Memory Info:")
print(f" RSS: {mem_info.rss / (1024**2):.2f} MB") # Resident Set Size
print(f" VMS: {mem_info.vms / (1024**2):.2f} MB") # Virtual Memory Size
print(f" USS: {process.memory_full_info().uss / (1024**2):.2f} MB") # Unique Set Size
print(f" PSS: {process.memory_full_info().pss / (1024**2):.2f} MB") # Proportional Set Size
print(f" Memory %: {mem_percent:.1f}%")
except psutil.NoSuchProcess:
print(f"Process {pid} not found")
def monitor_memory(interval=1, duration=60):
"""监控内存使用情况"""
print(f"Monitoring memory for {duration} seconds (interval: {interval}s)")
print("Press Ctrl+C to stop\n")
start_time = datetime.datetime.now()
end_time = start_time + datetime.timedelta(seconds=duration)
try:
while datetime.datetime.now() < end_time:
memory = psutil.virtual_memory()
swap = psutil.swap_memory()
timestamp = datetime.datetime.now().strftime("%H:%M:%S")
print(f"[{timestamp}] "
f"RAM: {memory.percent:5.1f}% ({memory.used/(1024**3):.1f}/{memory.total/(1024**3):.1f} GB) "
f"SWAP: {swap.percent:5.1f}%")
import time
time.sleep(interval)
except KeyboardInterrupt:
print("\nMonitoring stopped by user")
if __name__ == "__main__":
import os
get_memory_info()
get_process_memory()
monitor_memory(interval=2, duration=10)
直接解析 /proc/meminfo
def parse_proc_meminfo():
"""直接解析 /proc/meminfo"""
mem_info = {}
with open('/proc/meminfo', 'r') as f:
for line in f:
if ':' in line:
key, value = line.split(':', 1)
# 移除单位 kB,转换为整数
value = value.strip().split()[0]
mem_info[key] = int(value)
return mem_info
# 使用示例
mem_info = parse_proc_meminfo()
print(f"MemTotal: {mem_info['MemTotal'] / 1024:.2f} MB")
print(f"MemAvailable: {mem_info['MemAvailable'] / 1024:.2f} MB")
3.3 其他编程语言示例
Go 语言示例
package main
import (
"fmt"
"io/ioutil"
"strconv"
"strings"
)
type MemoryInfo struct {
Total uint64
Free uint64
Available uint64
Buffers uint64
Cached uint64
SwapTotal uint64
SwapFree uint64
}
func readUintFromFile(path string) (uint64, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
return 0, err
}
content := strings.TrimSpace(string(data))
// 移除 kB 单位
if strings.HasSuffix(content, " kB") {
content = content[:len(content)-3]
}
value, err := strconv.ParseUint(content, 10, 64)
if err != nil {
return 0, err
}
return value, nil
}
func getMemoryInfo() (*MemoryInfo, error) {
info := &MemoryInfo{}
var err error
info.Total, err = readUintFromFile("/proc/meminfo")
if err != nil {
return nil, err
}
// 跳过 MemFree,继续读取其他字段...
// 实际应用中需要读取所有相关字段
// 这里简化处理
info.Free, _ = readUintFromFile("/proc/meminfo") // 实际需要分别读取
return info, nil
}
func main() {
info, err := getMemoryInfo()
if err != nil {
fmt.Printf("Error reading memory info: %v\n", err)
return
}
fmt.Printf("Total Memory: %d kB\n", info.Total)
}
4. 高级监控与可视化
4.1 使用 collectd 进行长期监控
# 安装collectd
sudo apt install collectd
# 配置collectd监控内存
echo '
LoadPlugin memory
<Plugin memory>
ValuesPercentage false
</Plugin>
' | sudo tee -a /etc/collectd/collectd.conf
# 重启服务
sudo systemctl restart collectd
4.2 使用 Grafana + Prometheus 可视化
# prometheus.yml 配置
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
# 使用 node_exporter 暴露系统指标
./node_exporter
# 在Prometheus中查询内存使用率
# (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
4.3 自定义监控脚本
#!/bin/bash
# memory_monitor.sh - 综合内存监控脚本
LOG_FILE="/var/log/memory_monitor.log"
THRESHOLD=90 # 内存使用率阈值
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}
check_memory_usage() {
local mem_usage=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}')
local mem_usage_int=${mem_usage%.*}
log_message "Memory Usage: ${mem_usage}%"
if [ $mem_usage_int -gt $THRESHOLD ]; then
log_message "WARNING: Memory usage exceeds threshold ($THRESHOLD%)!"
# 找出内存使用最高的进程
log_message "Top memory consuming processes:"
ps aux --sort=-%mem | head -5 | tee -a $LOG_FILE
# 可以在这里添加告警逻辑(邮件、短信等)
# send_alert "High memory usage: ${mem_usage}%"
fi
}
# 主循环
while true; do
check_memory_usage
sleep 60 # 每分钟检查一次
done
5. 性能调优与故障排查
5.1 内存泄漏检测
# 使用 valgrind 检测内存泄漏
valgrind --leak-check=full ./your_program
# 使用 pmap 监控进程内存增长
pmap -x <pid> | tail -n 1
# 定期记录进程内存使用
while true; do
ps -p <pid> -o pid,rss,vsz,comm
sleep 10
done
5.2 OOM(Out Of Memory)分析
# 查看OOM日志
dmesg | grep -i "out of memory"
journalctl -k | grep -i "oom"
# 查看OOM killer杀死的进程
grep -i "killed process" /var/log/syslog
# 调整OOM得分(谨慎使用)
echo -1000 > /proc/<pid>/oom_score_adj
5.3 缓存优化
# 清理页面缓存(需要root权限)
sync # 先将缓存数据写入磁盘
echo 1 > /proc/sys/vm/drop_caches # 清理页面缓存
echo 2 > /proc/sys/vm/drop_caches # 清理目录项和inode缓存
echo 3 > /proc/sys/vm/drop_caches # 清理所有缓存
# 调整swappiness(默认60,降低可减少swap使用)
echo 'vm.swappiness=10' >> /etc/sysctl.conf
sysctl -p
6. 总结与最佳实践
6.1 方法选择指南
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| 快速查看内存概览 | free -h | 简洁明了,信息足够 |
| 详细内存分析 | cat /proc/meminfo | 最全面、最权威的数据 |
| 实时进程监控 | htop | 交互式界面,信息丰富 |
| 历史数据分析 | sar | 长期趋势分析 |
| 编程获取 | /proc/meminfo 或 sysinfo() | 灵活可控 |
| 跨平台开发 | psutil (Python) | 统一API,支持多平台 |
6.2 关键要点
- 理解内存指标:区分
free、available、buff/cache的含义 - 选择合适工具:根据需求选择命令行工具或编程接口
- 注意权限:某些信息需要 root 权限才能获取
- 定期监控:建立长期监控机制,及早发现问题
- 结合上下文:内存使用高不一定代表有问题,需结合应用特性分析
6.3 实用技巧
- 使用
watch命令实时监控变化 - 结合
grep和awk提取关键信息 - 建立基线数据,便于异常检测
- 关注
MemAvailable而非MemFree来判断内存压力 - 定期检查 OOM 日志,预防系统崩溃
通过掌握这些方法,你可以全面了解 Linux 系统的内存状况,为系统优化和故障排查提供有力支持。
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END

























暂无评论内容