Ubuntu虚拟服务器内存占用过高排查求助
兄弟,我来帮你捋捋这个内存占用的问题——你碰到的系统层面和WordPress插件统计的内存差异其实挺常见的,咱们一步步拆解可能的内存“大户”:
先搞懂数值差异的原因
首先得明确:Query Monitor统计的仅仅是WordPress运行时PHP进程的内存占用,而htop显示的是整个服务器的内存使用,包括MySQL、Redis、Web服务器(Nginx/Apache)、系统缓存、后台进程等所有组件的总和,所以两者数值完全不在一个维度上,不用觉得矛盾。
逐个排查内存占用点
1. MySQL 配置可能留了太多冗余
你的my.cnf里max_connections = 400这个设置太夸张了!每天400个访客的站点,实际并发连接数撑死也就20-30,400的上限会让MySQL提前预留大量内存(每个连接会分配sort_buffer、join_buffer等小缓存,加起来每个连接可能几十MB),哪怕实际没用到这么多连接,预留的内存也会被算进系统内存占用里。
- 先查实际连接数:登录MySQL执行
SHOW GLOBAL STATUS LIKE 'Threads_connected';,看看平时到底用了多少连接; - 把
max_connections降到50-80就足够了; - 另外可以用
mysqladmin status或者SHOW VARIABLES LIKE '%buffer%';估算MySQL总内存占用:innodb_buffer_pool_size(512M) + key_buffer_size(64M) + (每个连接的缓存总和)*实际连接数,如果这个值接近你的内存总量,那MySQL就是主要内存消耗者。
2. Redis 的缓存占用
虽然你装了Redis,但也要看看它实际用了多少内存:
- 执行
redis-cli info memory,看used_memory_human字段,就能知道Redis缓存了多少数据。如果缓存了大体积的内容(比如全量的页面缓存、未设置过期时间的键),也会吃掉不少内存。
3. Web 服务器(Nginx/Apache)的进程占用
如果用的是Apache的prefork模式,每个子进程可能占用100-200MB内存,要是同时跑3-4个进程就会占几百MB;就算是Nginx,PHP-FPM的进程数如果设置太高也会吃内存:
- 用
ps aux --sort=-%mem | grep apache2(或nginx/php-fpm)看每个进程的内存占用,把这些进程的RSS(常驻内存)加起来,就能算出Web服务的总内存消耗; - 如果是PHP-FPM,调整
pm.max_children参数,根据你的内存总量来算:比如每个PHP进程占50MB,2GB内存的话,max_children设为20左右就够了。
4. 系统缓存(buff/cache)的“误解”
htop里的MEM包含了系统的buff和cache,这部分是Linux用来缓存磁盘数据的,属于“可回收”内存——当系统需要内存时,会自动释放这部分空间。你可以用free -h看真实的内存占用:
比如输出里的
used是进程实际占用的内存,buff/cache是缓存,available是真正可用的内存。如果是缓存占了很多,其实不用紧张,这是系统在利用空闲内存提升性能。
5. 其他后台进程
看看有没有没用的系统进程在偷偷占内存:
- 在htop里按
M键(按内存排序),看除了Web、MySQL、Redis之外的进程,有没有占内存较高的异常进程; - 检查 cron 任务、监控agent(比如DigitalOcean的监控)、日志进程等,有没有不必要的服务可以禁用。
快速排查命令总结
- 看内存详细分布:
free -h - 按内存排序看进程:
htop(按M键) - 查MySQL连接数:
mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_connected';" - 查Redis内存:
redis-cli info memory - 查Web/PHP进程内存:
ps aux --sort=-%mem | grep php-fpm(替换成你的Web服务名)
备注:内容来源于stack exchange,提问作者Mike Hermary

