首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux内存那些事儿:一文搞懂free命令里的6个神秘数字

Linux内存那些事儿:一文搞懂free命令里的6个神秘数字

作者头像
悠悠12138
发布2025-09-29 15:15:32
发布2025-09-29 15:15:32
7700
代码可运行
举报
运行总次数:0
代码可运行

昨天又有小伙伴问我,为什么Linux服务器明明还有很多内存,但是应用却报内存不足?看了一眼他发的free命令截图,我就知道问题出在哪了。说实话,刚开始接触Linux的时候,我也被这几个数字搞得一头雾水。

今天就来聊聊free命令输出的这6个数字到底是什么意思,相信看完之后你就不会再被Linux的内存管理搞糊涂了。

先来看看这个让人困惑的输出

当我们在Linux系统上执行free -h命令时,通常会看到这样的输出:

代码语言:javascript
代码运行次数:0
运行
复制
              total        used        free      shared  buff/cache   available
Mem:           7.8G        2.1G        1.2G        156M        4.5G        5.2G
Swap:          2.0G          0B        2.0G

第一次看到这个输出的时候,我的内心是崩溃的。什么叫used了2.1G,但是available却有5.2G?这数学是体育老师教的吗?

其实这里面涉及到Linux内存管理的一些核心概念,理解了这些概念,你就能明白为什么会出现这种看似矛盾的情况。

total:系统总内存,这个最好理解

total就是系统的总物理内存大小,这个没什么好说的。你买了8G内存条,这里显示的就是8G(当然会扣掉一些被内核占用的部分)。

不过有个小细节,有时候你会发现total显示的内存比你实际购买的要小一些。比如你买了8G内存,但是total只显示7.8G。这是正常的,因为有一部分内存被BIOS、内核等系统组件占用了。

我记得刚接触电脑那会儿,买了16G内存,结果发现系统只识别到15.6G,还以为是内存条有问题,其实这是正常现象。

used:已使用内存,但不是你想的那样

这个used是最容易让人误解的。很多人以为used就是应用程序实际使用的内存,其实不是这样的。

used包括了:

  • • 应用程序实际使用的内存
  • • 内核使用的内存
  • • 缓冲区和缓存使用的内存

所以你看到used很高,不代表你的应用程序真的用了那么多内存。很可能是Linux把大量内存用作了文件缓存。

我之前遇到过一个案例,服务器显示used了6G内存,开发同学吓坏了,以为是内存泄漏。结果一查发现大部分都是文件缓存,应用程序实际只用了1G多。

如何具体查看内存都被谁用了

说到这里,肯定有人要问了:既然used包含了这么多东西,那我怎么知道到底是应用程序用的多,还是缓存用的多呢?

这个问题问得好,我来教你几个实用的方法。

用/proc/meminfo看详细分解

最直接的方法就是查看/proc/meminfo文件,它会把内存使用情况拆分得很详细:

代码语言:javascript
代码运行次数:0
运行
复制
cat /proc/meminfo | grep -E "(MemTotal|MemFree|MemAvailable|Buffers|Cached|SReclaimable)"

输出大概是这样的:

代码语言:javascript
代码运行次数:0
运行
复制
MemTotal:        8048484 kB
MemFree:          524288 kB  
MemAvailable:    5242880 kB
Buffers:          204800 kB
Cached:          4096000 kB
SReclaimable:     512000 kB

这里面:

  • • Buffers就是缓冲区使用的内存
  • • Cached就是页面缓存使用的内存
  • • SReclaimable是可回收的内核数据结构

把这几个加起来,基本就是free命令里buff/cache那一列的值。

我经常用这个命令来快速判断内存都去哪了。如果Cached特别大,说明系统缓存了很多文件;如果Buffers很大,可能是有大量的磁盘IO操作。

用ps命令查看进程内存使用

想知道应用程序到底用了多少内存,最直接的就是看各个进程的内存占用:

代码语言:javascript
代码运行次数:0
运行
复制
# 按内存使用量排序显示进程
ps aux --sort=-%mem | head -10

# 或者用这个更直观的格式
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -10

这样你就能看到哪些进程是内存大户了。

image-20250918202445910
image-20250918202445910

image-20250918202445910

我还喜欢用这个命令来统计某个应用的总内存使用:

代码语言:javascript
代码运行次数:0
运行
复制
# 比如统计所有java进程的内存使用
ps aux | grep java | awk '{sum+=\$6} END {print "Total memory: " sum/1024 " MB"}'

free:真正空闲的内存

free显示的是完全没有被使用的内存。注意,这里不包括被用作缓冲区和缓存的内存,因为这些内存在需要的时候是可以立即释放给应用程序使用的。

所以你经常会看到free的值很小,这是正常的。Linux的设计哲学就是"空闲的内存是浪费的内存",系统会尽可能地把空闲内存用作文件缓存,提高系统性能。

有些刚接触Linux的同学看到free只有几百MB就紧张得不行,其实完全没必要。只要available够用就行。

shared:共享内存

shared显示的是被多个进程共享的内存大小。这部分内存主要包括:

  • • 共享内存段(System V shared memory)
  • • tmpfs文件系统使用的内存
  • • 一些其他的共享内存区域

说实话,在日常运维中,我很少特别关注这个数值。除非你的应用大量使用了共享内存,否则这个值通常不会很大。

我见过一些使用Redis的系统,如果Redis配置了大量的共享内存,这个值会比较高。但大多数情况下,这个数字都不是重点关注对象。

buff/cache:缓冲区和缓存

这个是Linux内存管理的精髓所在。buff/cache包括:

  • • 缓冲区(buffers):用于缓存磁盘块设备的数据
  • • 页面缓存(page cache):用于缓存文件内容

Linux会把空闲内存用作文件缓存,这样当程序再次读取相同文件时,就可以直接从内存中获取,而不需要再次访问磁盘。这大大提高了系统的IO性能。

关键是,这部分内存在应用程序需要时可以立即释放。所以虽然它们被标记为"已使用",但实际上是可用的。

我记得有一次优化一个文件服务器的性能,发现系统把大量内存用作了文件缓存。刚开始还担心内存不够用,后来发现这正是Linux智能内存管理的体现,文件访问速度提升了好几倍。

buff/cache的调整和优化

虽然Linux的内存管理已经很智能了,但在某些场景下我们还是需要适当调整。

手动清理缓存(谨慎使用)

代码语言:javascript
代码运行次数:0
运行
复制
# 清理页面缓存
echo 1 > /proc/sys/vm/drop_caches

# 清理所有缓存
sync && echo 3 > /proc/sys/vm/drop_caches

注意:生产环境别随便清理,会影响性能。

调整缓存策略

控制swap使用倾向:

代码语言:javascript
代码运行次数:0
运行
复制
# 查看当前值
cat /proc/sys/vm/swappiness

# 调整为10(让系统优先回收缓存而不是使用swap)
echo "vm.swappiness = 10" >> /etc/sysctl.conf

控制缓存回收压力:

代码语言:javascript
代码运行次数:0
运行
复制
# 调整目录和inode缓存回收
echo "vm.vfs_cache_pressure = 50" >> /etc/sysctl.conf

不同场景的优化建议

数据库服务器:

代码语言:javascript
代码运行次数:0
运行
复制
vm.swappiness = 1
vm.vfs_cache_pressure = 150

文件服务器:

代码语言:javascript
代码运行次数:0
运行
复制
vm.swappiness = 10  
vm.vfs_cache_pressure = 50

记住调整完要用sysctl -p生效,然后观察系统表现。大多数情况下默认设置就够用了,别没事瞎调。

available:真正可用的内存

这个是最重要的指标!available显示的是应用程序可以使用的内存总量,包括:

  • • free的内存
  • • 可以立即释放的buff/cache内存
  • • 一些其他可回收的内存

简单来说,available = free + 可回收的buff/cache

这个数值才是你真正需要关注的。当available很低的时候,才说明系统内存真的不够用了。

我现在判断系统内存是否充足,主要就看这个available值。只要它保持在一个合理的水平,就不用担心内存问题。

Swap的添加和关闭

查看当前swap状态

代码语言:javascript
代码运行次数:0
运行
复制
# 查看swap使用情况
free -h
swapon --show

添加swap文件

代码语言:javascript
代码运行次数:0
运行
复制
# 创建2G的swap文件
dd if=/dev/zero of=/swapfile bs=1M count=2048

# 设置权限
chmod 600 /swapfile

# 格式化为swap
mkswap /swapfile

# 启用swap
swapon /swapfile

# 永久生效,添加到fstab
echo '/swapfile none swap sw 0 0' >> /etc/fstab
image-20250918205004240
image-20250918205004240

image-20250918205004240

关闭和删除swap

代码语言:javascript
代码运行次数:0
运行
复制
# 关闭swap
swapoff /swapfile

# 从fstab中删除对应行
sed -i '/swapfile/d' /etc/fstab

# 删除swap文件
rm /swapfile

调整swap分区大小

如果是swap分区而不是文件,需要用fdisk重新分区,比较麻烦。所以我一般推荐用swap文件,灵活性更好。

记住,SSD硬盘上频繁swap会影响寿命,能加内存就别用太多swap。

一个实际的例子来说明

让我用一个真实的例子来解释这些概念。假设我们有一台8G内存的服务器:

代码语言:javascript
代码运行次数:0
运行
复制
              total        used        free      shared  buff/cache   available
Mem:           7.8G        3.2G        0.5G        200M        4.1G        4.3G

看起来used了3.2G,free只有0.5G,是不是内存很紧张?

其实不是的。让我们分析一下:

  • • 应用程序实际使用的内存可能只有1.5G左右
  • • 剩下的1.7G是buff/cache,用于文件缓存
  • • available显示4.3G,说明系统还有充足的可用内存

如果这时候启动一个需要2G内存的应用,系统会自动释放一部分文件缓存,为新应用腾出空间。

内存不足时会发生什么

当available真的很低时,Linux会启动一些内存回收机制:

  1. 1. 首先释放不必要的缓存
  2. 2. 如果还不够,会使用swap空间
  3. 3. 最极端的情况下,OOM Killer会杀掉一些进程

我遇到过几次OOM的情况,通常是因为某个应用出现了内存泄漏,把available耗尽了。这时候系统日志里会有相关记录,可以通过dmesg命令查看。

如何监控内存使用情况

除了free命令,还有一些其他工具可以帮助我们监控内存:

cat /proc/meminfo可以看到更详细的内存信息:

代码语言:javascript
代码运行次数:0
运行
复制
cat /proc/meminfo | head -20

tophtop命令可以看到各个进程的内存使用情况。

对于生产环境,我建议设置监控告警。当available内存低于某个阈值时(比如总内存的10%),就发送告警通知。

一些常见的误区

很多人看到used很高就以为内存不够用了,这是最大的误区。记住,只有available才是真正需要关注的指标。

还有人喜欢手动清理缓存:

代码语言:javascript
代码运行次数:0
运行
复制
echo 3 > /proc/sys/vm/drop_caches

其实这通常是没必要的,甚至可能降低系统性能。Linux的内存管理机制已经很智能了,不需要我们手动干预。

我见过有些运维同学定期清理缓存,以为这样可以释放内存。其实这样做反而会降低系统性能,因为清理掉的缓存很快又会被重新建立。

还有一个误区是认为swap使用就代表内存不够。其实少量的swap使用是正常的,Linux会把一些不活跃的内存页面换出到swap,为活跃的数据腾出更多内存空间。只有当swap使用率很高,或者系统频繁进行swap操作时,才需要担心。

不同版本的差异

顺便说一下,不同版本的Linux在free命令输出上可能有些差异。

在比较老的系统上,你可能看不到available这一列,那时候我们通常用这个公式来估算可用内存:

代码语言:javascript
代码运行次数:0
运行
复制
可用内存 ≈ free + buffers + cached

但这个估算并不准确,因为不是所有的buffers和cached都可以被释放。所以现在的系统直接提供了available这个更准确的数值。

容器环境下的特殊情况

现在很多应用都跑在Docker容器里,容器的内存统计会有一些特殊性。

在容器内执行free命令看到的是宿主机的内存信息,而不是容器被分配的内存。要查看容器的内存限制和使用情况,需要用其他方法:

代码语言:javascript
代码运行次数:0
运行
复制
# 查看容器内存限制
cat /sys/fs/cgroup/memory/memory.limit_in_bytes

# 查看容器内存使用
cat /sys/fs/cgroup/memory/memory.usage_in_bytes
image-20250918211312186
image-20250918211312186

image-20250918211312186

我之前就遇到过一个坑,容器内的应用报内存不足,但是free命令显示宿主机内存充足。后来才发现是容器的内存限制设置得太小了。

性能调优的一些思考

理解了这些内存概念之后,我们在做性能调优时就有了更清晰的思路。

如果发现系统IO性能不好,但是buff/cache很小,说明文件缓存没有充分利用。这时候可以考虑增加内存,让系统有更多空间用作文件缓存。

如果available经常很低,但是应用程序实际使用的内存并不多,可能是某些进程存在内存泄漏。这时候需要用工具分析具体是哪个进程在消耗内存。

我曾经优化过一个Web服务,发现它的响应时间很慢。分析后发现是因为内存不足,系统频繁进行磁盘IO。增加了内存之后,大量文件被缓存在内存中,响应时间提升了好几倍。

一些实用的命令组合

在日常工作中,我经常用这些命令组合来快速了解系统内存状态:

代码语言:javascript
代码运行次数:0
运行
复制
# 查看内存使用情况,按人类可读格式显示
free -h

# 每秒更新一次内存信息
watch -n 1 free -h

# 查看详细的内存信息
cat /proc/meminfo | grep -E "(MemTotal|MemFree|MemAvailable|Buffers|Cached)"

# 查看各进程内存使用排序
ps aux --sort=-%mem | head -10

有时候我还会写个简单的脚本来持续监控内存变化:

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash
while true; do
    echo "$(date): $(free -h | grep Mem)"
    sleep 60
done

这样可以观察内存使用的变化趋势,对于排查间歇性的内存问题很有帮助。

写在最后

理解Linux的内存管理机制对于运维和开发都很重要。记住这几个要点:

  1. 1. total是总内存,这个最直观
  2. 2. used包括了应用程序和缓存使用的内存
  3. 3. free是完全空闲的内存,通常很小
  4. 4. buff/cache是可以释放的缓存内存
  5. 5. available是真正可用的内存,这个最重要
  6. 6. shared是共享内存,通常不用太关注

下次再看到free命令的输出,你就不会被那些数字搞糊涂了。Linux的内存管理确实很智能,我们要做的就是理解它的工作原理,而不是跟它对着干。

说实话,刚开始学Linux的时候,我也经常被这些概念搞得头大。但是随着经验的积累,慢慢就理解了Linux设计者的良苦用心。现在回过头看,这套内存管理机制真的很优雅,既保证了系统性能,又最大化了内存利用率。

最后想说的是,内存管理是个很深的话题,这篇文章只是入门级的介绍。如果你想深入了解,建议去看看《深入理解Linux内核》这本书,里面有更详细的技术细节(后台私信可以免费领取电子版哈!)

当然了,对于大多数运维工作来说,理解这些基本概念就够用了。关键是要在实践中多观察、多思考,多重复的练习。重复多了就是积累,积累多了就是经验,经验多了就是应变!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维躬行录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 先来看看这个让人困惑的输出
  • total:系统总内存,这个最好理解
  • used:已使用内存,但不是你想的那样
  • 如何具体查看内存都被谁用了
    • 用/proc/meminfo看详细分解
    • 用ps命令查看进程内存使用
  • free:真正空闲的内存
  • shared:共享内存
  • buff/cache:缓冲区和缓存
  • buff/cache的调整和优化
    • 手动清理缓存(谨慎使用)
    • 调整缓存策略
    • 不同场景的优化建议
  • available:真正可用的内存
  • Swap的添加和关闭
    • 查看当前swap状态
    • 添加swap文件
    • 关闭和删除swap
    • 调整swap分区大小
  • 一个实际的例子来说明
  • 内存不足时会发生什么
  • 如何监控内存使用情况
  • 一些常见的误区
  • 不同版本的差异
  • 容器环境下的特殊情况
  • 性能调优的一些思考
  • 一些实用的命令组合
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档