Z次元
文章 笔记 日志
专题
专栏分类 文章归档
友链
友情链接 朋友圈
留言
头像
系列文章
云服务器内存严重缩水?4G内存为何只有3G可用?
系列文章
杂谈随笔
最后更新:2024/12/15|创建时间:2024/5/13
文章摘要
文章讨论了云服务器内存占用异常问题,服务器实际可用内存缩水的现象。作者通过free命令分析内存使用情况,发现缓存占用大量内存。解释了Linux内核通过缓存机制优化文件读写效率,但缓存不会自动释放,导致可用内存减少。文章提供了手动清理缓存的方法和工具hcache的使用,帮助诊断内存占用问题。

前言

最近总算是把博客项目基本写完了,但是部署到服务器上时,服务器直接爆了。。。

但是令人不解的是,服务器4G内存,只用了3G,怎么就用不了了,服务器直接卡死了。

图片

为何为出现如此严重的缩水?

先使用 free命令查看下内存情况:

$ free

free命令默认以KB为单位,可选参数为:-b、-k、-m、-g

参数说明:

总内存(Total):显示系统的总内存大小。
已使用内存(Used):显示当前已被分配和使用的内存大小。
剩余内存(Free):显示当前剩余可用的内存大小。
共享内存(Shared):显示被多个进程共享的内存大小。
缓存(Buffers):显示用于缓存文件系统数据的内存大小。
缓冲区(Cached):显示用于缓冲磁盘写操作的内存大小。

图片

可以看到总共有3669M可用内存(相当于实际还是缩水了300M。。。),已使用1938M,但是空闲空间只剩141M,缓存占用高达1589M。

为什么缓存占用如此之高呢?

在服务内存够用的情况下,Linux内核为了加快对文件的读写效率会将文件放入之 buffer/cache 中 以保证读写效率,但其实,尽管当你的应用程序对文件的读写运行结束后,buffer/cache 也不会自动释放该部分内存,而是作为缓冲进行保留,等到你的服务进程在下一次进行相同文件的读写时就可以直接使用,省去了各种重新进行内存初始化的操作;所以这将会导致,当你的应用进程频繁对不同的文件进行读写时,你会发现服务所可以直接使用的free内存将会越来越少的一个重要原因;难道 buffer/cache 在这样无休止的缓存当中就不会自动释放?当然不是,当服务器在内存压力较大的情况下时,则将会自动进行内存的回收,作为free空间分给其它进程使用,这其中主要回收的一个内存则是 buffer/cache 的缓冲区内存块。

如何手动回收缓存?

除了在系统进程内存使用较大压力的情况下进行内存的回收外,我们也可以进行手动的buffer/cache回收,但由于buffer/cache主要是用于文件的读写使用,所以进行文件回收时,一般常伴随系统的IO彪高,因为系统内核也对比cache中的数据与硬盘中的数据是否一致,如果不一致需要写入,然后才能进行内存的回收。

## 将内存中数据强制先刷新到磁盘中
$ sync
 
## 清理Buffer缓存区域
# echo 1 > /proc/sys/vm/drop_caches  # 表示清除pagecache。
# echo 2 > /proc/sys/vm/drop_caches  # 表示清除回收slab分配器中的对象(包括目录项缓存和inode缓存)。slab分配器是内核中管理内存的一种机制,其中很多缓存数据实现都是用的pagecache。
# echo 3 > /proc/sys/vm/drop_caches  # 表示清除pagecache和slab分配器中的缓存对象

非root用户使用以下命令执行:

$ sudo sh -c 'echo 1 > /proc/sys/vm/drop_caches'
$ sudo sh -c 'echo 2 > /proc/sys/vm/drop_caches'
$ sudo sh -c 'echo 3 > /proc/sys/vm/drop_caches'

清理完后可以看到可用内存变成了1317M:

图片

排除缓存过高的原因

如果想知道是什么进程引起的缓存过高,可以安装hcache工具进行排查:

$ wget https://silenceshell-1255345740.cos.ap-shanghai.myqcloud.com/hcache -O /usr/local/bin/hcache ;\
chmod +x /usr/local/bin/hcache

常用命令:

$ hcache --top 10           # 全局显示10个最大的被缓存文件
$ lsof /usr/lib/vmware-tools/lib64/libxerces-c-3.1.so/libxerces-c-3.1.so
# 根据文件找到对应的进程、pid
$ hcache -pid 1070   # 获取当前进程号所打开的所有文件信息
$ lsof -p 1070     # 获取当前进程号所打开的所有文件信息(二选一)

后记

经过了一番折腾总算是把项目部署到云服务器上了。服务器内存直接干掉5个G,3G的物理内存+2G的虚拟内存。

由于项目很多东西都是部署在磁盘转换的虚拟内存上,导致性能不太行,加载速度不是很乐观,只能等后续优化了= =+。

版权声明
本文依据 CC-BY-NC-SA 4.0 许可协议授权,请您在转载时注明文章来源为 Z次元 ,若本文涉及转载第三方内容,请您一同注明。
更多专栏文章推荐
杂谈随笔
生活不止眼前的苟且,还有诗和远方。。。
超好用的免费开源win11复刻win10磁吸菜单的工具分享
2023/6/17
来尝试下最近很火的ChatGPT,AI究竟智能到何种程度?
2022/12/8
腾讯云限时免费升配活动再次来袭
2024/9/29
关于站点受到了大量未知访问路径这件事
2024/9/17
评论区

删除确认

评论删除后无法恢复,请确认是否继续?
发表评论
删除 编辑 回复
i

1

inleft2024年6月6日

java一大特色就是笨重,吃内存,个人服务器如果搭载1个jar包+mysql+es,一套组合拳下来,没有4-5g搞不定,我都是往轻量级的应用走,能不用第三方就自己手写,maven套上一个依赖,给你多整上几个用不到包太常见了,如果有得选,我宁愿学c++

删除 编辑 回复
柒

2

柒 博主 @inleft2024年6月7日

emmmm,其实没那么夸张,正常一个java程序大概占用400M左右内存

删除 编辑 回复
b

1

btwoa2024年5月14日

配置高了拿来跑博客还是会心疼的

删除 编辑 回复
柒

2

柒 博主 @btwoa2024年5月15日

是的,但是服务器还可以部署其它项目的嘛棒棒糖

删除 编辑 回复
柒

1

柒 博主 2024年5月13日

一番折腾下来,发现根本就没用,开个es马上又没内存了,下次得换个更大内存的服务器才行了。。。。

前言
为何为出现如此严重的缩水?
如何手动回收缓存?
排除缓存过高的原因
后记
目录
前言
为何为出现如此严重的缩水?
如何手动回收缓存?
排除缓存过高的原因
后记
博客
文章 笔记 日志
专题
专栏分类 文章归档
友链
友情链接 朋友圈
交流
留言 关于我
主页
菜单
置顶
主题
我的
十玖八柒
每天进步多一点
欢迎到访φ(゜▽゜*)♪
最新评论
个人占星:
DeepSeek没有想象中的好用
个人占星:
想给自己的网站弄个统计功能,但不会弄,头疼
永恒末匕:
好哇塞,这个厉害
十玖八柒:
测试图片发送
我的
关于我
个人主页
站点地图
RSS订阅
导航
十年之约
虫洞穿梭
开源博客
前端开源仓库
后端开源仓库
©2020 - 2025 By 十玖八柒 版权所有
豫ICP备20021466号