Ubuntu VPS内存占用高,很多人第一反应是去调swappiness、清缓存、甚至加swap。这些操作不能说错,但往往绕开了真正值得先处理的东西。一台默认安装的Ubuntu Server上,有两类内存占用是你可以干净利落地砍掉的:一个是apport,Ubuntu的错误报告服务,平时悄无声息地占着内存和进程槽位,绝大多数VPS场景根本用不上它;另一个是旧内核,它们不直接吃运行内存,但会通过/boot分区压力、引导菜单膨胀以及潜在的模块加载冗余,间接拖累系统整体的轻量程度。
先把这两件事做了,再去看其他优化手段,顺序上更合理。
先搞清楚:你看到的“高”到底是不是真高
动手之前,先花一分钟确认内存压力是否真实存在。Ubuntu和大多数Linux发行版一样,会把空闲内存拿去做文件缓存,free -h里used数字大不代表内存不够用。真正值得看的是available这一列,以及swap有没有在被频繁使用。
free -h
如果available还有总内存的百分之二三十以上,swap的used很低或者为零,那内存状况其实是健康的,不需要为了“used看起来高”而大动干戈。但如果available持续偏紧,或者swap在涨,下面两个操作就有了明确的靶子。
第一步:关掉apport,把错误报告服务停掉
apport是Ubuntu默认启用的崩溃报告收集服务。程序崩溃时,它会生成一份详细的报告,存到/var/lib/apport/coredump或者/var/crash下面,有时候还会尝试把报告发出去。对于桌面用户,这东西在调试时有点用;对于VPS,它几乎纯粹是负担:多一个常驻进程,多一份内存开销,崩溃时还可能因为生成报告而让本已紧张的内存雪上加霜。
关掉它的操作很直接。先改配置文件:
sudo nano /etc/default/apport
找到enabled=1这一行,改成:
enabled=0
保存退出。然后停掉正在运行的apport服务,并禁止它开机自启:
sudo systemctl stop apport
sudo systemctl disable apport
有些系统上apport是通过service命令管理的,如果systemctl提示找不到服务,用这个:
sudo service apport stop
改完之后可以用ps aux | grep apport确认一下没有残留进程。这一步不会释放出惊人的内存量,但它的意义在于:消除一个你不需要的、随时可能因为某个程序崩溃而突然活跃起来的后台服务。对于内存本来就紧的VPS,这种“潜在的内存消耗点”越少越好。
第二步:清理旧内核,别让/boot和模块目录越堆越臃肿
Ubuntu每次内核更新,旧版本默认不会被删掉。跑上一年半载,/boot里可能躺着四五个甚至更多内核镜像。它们占的是磁盘空间,不是运行内存,但间接影响不小:/boot分区(很多VPS默认只给几百MB)被塞满后,后续内核更新会失败,apt会卡在一半;/lib/modules/下对应的旧模块目录也一直留着,depmod和模块搜索的负担在长期运行中并非完全为零。
清理旧内核有一个铁律:绝对不能删当前正在运行的那个版本。先确认它:
uname -r
输出类似5.15.0-91-generic。记住这个字符串,后面无论手动删还是自动删,都要确保它被排除在外。
最省事、也最安全的方式是让apt自己判断:
sudo apt autoremove --purge
这个命令会删掉“自动安装且不再被需要”的包,其中就包括旧内核。--purge的作用是连配置文件一起清掉,避免残留。执行前它会列出将要删除的内容,扫一眼,确认当前uname -r的版本不在列表里,就可以继续。
如果你想要更精确的控制,或者autoremove因为某些依赖关系没有把该删的删干净,可以手动指定。先列出所有已安装的内核相关包:
dpkg --list | grep -E 'linux-image|linux-headers|linux-modules'
找到你想删的旧版本号,比如5.15.0-78-generic,然后执行:
sudo apt purge linux-image-5.15.0-78-generic linux-headers-5.15.0-78-generic linux-modules-5.15.0-78-generic
版本号后面的-generic要跟实际输出对上。如果某个包不存在,apt会提示,不影响其他包的删除。删完之后再跑一次sudo apt autoremove --purge清理可能残留的依赖。
有一种情况需要额外留意:/boot已经满了,导致apt连autoremove都跑不起来,报错说空间不足。这时候需要先手动删掉一两个最旧的内核文件(/boot/vmlinuz-旧版本和/boot/initrd.img-旧版本),腾出空间让apt能正常工作,然后再用autoremove把包状态清理干净。手动删文件这一步有风险,务必先ls /boot看清楚文件名,确认删的不是uname -r对应的那个。
清理完成后,刷新一下GRUB菜单,让启动项里不再出现已删除的内核:
sudo update-grub
再用df -h /boot看一眼,空间应该明显宽裕了。
这两个操作之后,再看什么
关掉apport、清完旧内核,回到free -h和top,看看available有没有改善,swap的使用是否有所回落。如果改善有限,说明内存压力另有来源,这时候再按优先级往下查。
先看进程。用ps aux --sort=-rss | head -15找出实际吃内存最多的几个进程,看看它们是正常业务进程还是有什么东西在异常增长。如果某个进程的RSS在业务量稳定的情况下持续爬升,重启后才回落,那才是内存泄漏的线索,需要从应用层面排查。
如果进程侧看不出明显问题,但available就是紧张,可以适度调整swappiness。Ubuntu默认vm.swappiness=60,在VPS上往往偏高,调到10到20之间能让内核更倾向于保留物理内存、少往磁盘上换页。修改方式:
sudo sysctl vm.swappiness=10
要让重启后生效,写入/etc/sysctl.d/下的配置文件:
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/60-swappiness.conf
sudo sysctl --system
对于内存特别小的VPS(比如1GB或2GB),还可以考虑启用zram,用压缩后的内存块充当swap,比磁盘swap快得多,相当于给物理内存做了一个低成本的“扩容”。不过这是另一个话题,关掉apport和清旧内核之后如果仍然吃紧,再考虑往这个方向走。
相关问答:
问:apport关掉之后,系统出问题了我怎么知道?
答:VPS上你真正需要关注的“系统出问题”通常不是某个桌面程序崩溃,而是服务挂了、磁盘满了、内存爆了。这些靠systemctl status、dmesg、监控告警都能发现,不需要apport的崩溃报告。如果你在跑开发环境、需要调试某个频繁崩溃的程序,可以临时把enabled改回1并start服务,用完再关。
问:清完旧内核,/boot还是满的,怎么办?
答:检查是不是有残留的旧内核文件没有对应的包记录。ls /boot看看有没有明显过时的vmlinuz-*或initrd.img-*文件,对照dpkg -l | grep linux-image的输出,如果某个文件对应的包已经不存在了,可以手动删除。另外看看/boot里有没有其他大文件,比如老的memtest86+镜像或者你自己放进去的东西。
问:内存占用高,但available很充足,还需要做这些吗?
答:做不做都可以。关apport和清旧内核本身是低风险的卫生操作,做了没坏处,但不做也不会因为“used高”而出问题。如果你的available健康、swap为零,优化优先级应该放在别的地方,比如审视有没有不需要的服务在跑、日志有没有在无限膨胀。
推荐文章