Linux服务器Cache占用过多内存导致系统内存不足最终java应用程序崩溃解决方案

本文介绍了一种解决Linux系统中内存占用过高的方法,特别是针对由文件缓存导致的内存占用问题。通过定期清理缓存,有效避免了Java应用程序因内存不足而崩溃的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

Linux内存使用量超过阈值,使得Java应用程序无可用内存,最终导致程序崩溃。即使在程序没有挂掉时把程序停掉,系统内存也不会被释放。


找原因的过程

这个问题已经困扰我好几个月了,分析过好多次都没有找到原因,网上查了一下该问题其他人也都遇到过,不过并没有什么好的解决方案,因为项目一直没有上线,每次当内存不足时导致程序崩溃都是重启服务就好了,索性也就没花太多的时间来找问题。现在项目马上上线了,不能在出现程序崩溃的情况了,况且还是前置系统,更不能出现任何问题。

最开始一直认为是程序的原因导致内存泄漏,使用jdk自带的jmap -F -dump:live,format=b,file=/usr/local/sztFront/logs/heapdump.bin命令输出过几次dump文件,通过MemoryAnalyzer分析,应用程序没有耗内存过大的变量。后台猜测是否日志输出过多导致的,毕竟是前置系统,每天的报文量特别大,日志能到达5,6个G。所以把日志接收报文关了,日志大小马上降下来了,每天200M。程序挂掉的时间变长了,原来差不多一周就挂掉了,现在可以达到两周左右才挂掉,还是不行,没有冲根本上解决问题。经过在网上搜索各种相关的问题,问题出现在Cached的值过大,导致系统没有可以再分配的内存空间。Cached只要用来缓存文件的,经常读写的文件会被缓存到Cached中,可以增加读写效率,该功能是Linux系统内核提供的,从2.6.16以后的核心版本才提供,也就是老版的操作系统,如红旗DC 5.0、RHEL 4.x之前的版本都没有这就可以解释为什么我的项目总挂掉了,我的项目主要就是处理文件的,所以接收和下载的文件会被缓存起来,一直耗着内存不释放,即使把程序停掉也不会释放内存。最后找到了三条执行,可以清理cached的内存

三条指令:

sync

echo 1 > /proc/sys/vm/drop_caches
echo 2 > /proc/sys/vm/drop_caches
echo 3 > /proc/sys/vm/drop_caches

执行完这三条指令后通过free -m命令查看,free可用内存马上增多,buff/cache列值变小,说明内存被释放了,但是不能总是手动的执行这三条指令,所以最后写了一个shell脚本,开启Linux定时任务crond,每天早上检查一次free内存,当小于4G时执行这三条命令(注:系统内容20G)。

注意:在执行这三条命令之前一定要先执行sync命令(描述:sync 命令运行 sync 子例程。如果必须停止系统,则运行sync 命令以确保文件系统的完整性。sync 命令将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-Node、已延迟的块 I/O 和读写映射文件


解决方案(手动)

1. 修改/proc/sys/vm/drop_caches,释放Slab占用的cache内存空间(参考drop_caches的官方文档):

Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free.
To free pagecache:
* echo 1 > /proc/sys/vm/drop_caches
To free dentries and inodes:
* echo 2 > /proc/sys/vm/drop_caches
To free pagecache, dentries and inodes:
* echo 3 > /proc/sys/vm/drop_caches
As this is a non-destructive operation, and dirty objects are notfreeable, the user should run "sync" first in order to make sure allcached objects are freed.
This tunable was added in 2.6.16.

注意:在执行这三条命令前先执行sync命令


解决方案(自动)

1、编写shell定时任务脚本freemem.sh

#! /bin/sh
used=`free -m | awk 'NR==2' | awk '{print $3}'`
free=`free -m | awk 'NR==2' | awk '{print $4}'`
echo "===========================" >> /app/memory/logs/mem.log
date >> /app/memory/logs/mem.log
echo "Memory usage before | [Use:${used}MB][Free:${free}MB]" >> /app/memory/logs/mem.log
if [ $free -le 4000 ] ; then
                sync && echo 1 > /proc/sys/vm/drop_caches
                sync && echo 2 > /proc/sys/vm/drop_caches
                sync && echo 3 > /proc/sys/vm/drop_caches
				used_ok=`free -m | awk 'NR==2' | awk '{print $3}'`
				free_ok=`free -m | awk 'NR==2' | awk '{print $4}'`
				echo "Memory usage after | [Use:${used_ok}MB][Free:${free_ok}MB]" >> /app/memory/logs/mem.log
                echo "OK" >> /app/memory/logs/mem.log
else
                echo "Not required" >> /app/memory/logs/mem.log
fi
exit 1

2、使用crontab -e命令编辑当前用户的crontab

0 6 * * * /usr/local/tomcat/sztFileFront/bin/freemem.sh

定时任务编写参考:http://www.jb51.net/article/15008.htm


3、重启crond服务

/sbin/service crond restart

4、查看crond服务是否重启成功

/sbin/service crond status



最后,问题解决。我设定的定时任务是每天早上6点执行一次freemem.sh脚本。













<think>嗯,用户问的是如何判断服务器内存不足。我需要先理解用户的需求。可能用户是系统管理员,或者是开发人员,遇到了服务器性能问题,想排查是不是内存不够用。他们可能已经注意到服务器变慢、应用崩溃,或者监控系统发出警报,想确认是否是内存问题。 首先,我得回忆一下常见的检查内存的方法。通常,在Linux系统里,可以用free命令查看内存使用情况,或者top、htop这些工具。Windows的话,任务管理器或者性能监视器。不过用户可能更熟悉Linux,因为服务器常用。 然后要考虑内存不足的表现。比如,free命令中available很少,swap使用率高,或者出现OOM Killer的日志。这些都是关键点。另外,缓存(cache)和缓冲(buffer)的区别也需要解释清楚,因为有时候用户看到used很高,但其实是缓存,实际可用内存可能还够。 还要想到其他可能的问题,比如内存泄漏,或者某个进程占用过多内存。这时候需要检查进程的内存使用情况,比如用ps或者top排序。另外,监控工具如Prometheus、Zabbix的设置,可能用户想长期监控,所以得提到设置警报阈值。 用户可能不太清楚如何具体操作,比如查看OOM日志的位置,或者如何配置监控。这时候需要给出具体的命令,比如grep -i oom /var/log/syslog,或者解释vmstat的输出含义。还要注意解释术语,比如swapiness,避免用户混淆。 另外,用户可能想知道临时解决方案和长期解决方案。比如临时释放内存的方法,如清理缓存,或者终止进程。长期的话,增加内存、优化应用代码、调整配置等。需要分点说明,结构清晰。 可能存在的误区是,用户看到内存使用率高就以为不足,但实际上Linux会利用空闲内存做缓存,这部分是可释放的。所以需要强调available字段的重要性,而不仅仅是used。这也是常见的混淆点,需要特别指出。 最后,确保回答覆盖了不同操作系统,比如Linux和Windows,但主要侧重Linux,因为服务器环境。同时,给出实际案例,比如当available接近零,swap使用增加,这时候可能内存不足,帮助用户理解判断依据。 总结下来,回答的结构应该是先介绍检查方法,包括命令和工具,再说明判断指标,然后给出解决方案,最后补充注意事项或案例。这样用户能一步步排查,确认问题并采取相应措施。</think>判断服务器内存是否不足,可以通过以下方法和指标进行排查和分析: --- ### **一、检查内存使用情况** #### **1. 使用命令行工具(Linux系统)** - **`free -h` 命令** 查看内存总量、已用内存、空闲内存、缓存(Cache)和缓冲(Buffer)等信息。 **关键指标**: - `available`:系统可用内存(包括未被使用的内存和可回收的缓存)。 - 如果 `available` 接近 0,且 `free` 内存极少,可能内存不足。 - **`top` 或 `htop` 命令** 实时监控内存使用情况,按内存占用排序(在 `top` 界面按 `Shift+M`)。 **关注列**: - `%MEM`:进程占用物理内存的百分比。 - `VIRT`:进程使用的虚拟内存总量。 - **`vmstat 1` 命令** 查看内存、交换分区(swap)、I/O 等动态信息。 **关键指标**: - `si`(swap-in):每秒从磁盘读入内存的数据量(单位 KB)。 - `so`(swap-out):每秒从内存写入磁盘的数据量。 若 `si`/`so` 持续较高,说明物理内存不足,系统频繁使用交换分区。 --- #### **2. 监控工具(通用)** - **图形化工具**:如 `nmon`(Linux)、任务管理器(Windows)、`glances` 等。 - **专业监控系统**:Zabbix、Prometheus + Grafana、Nagios 等,可设置内存阈值告警(如使用率超过 90%)。 --- ### **二、内存不足的典型表现** 1. **系统响应变慢** - 应用程序卡顿,SSH 登录延迟高。 - 频繁触发交换分区(swap),导致磁盘 I/O 增加(机械硬盘尤其明显)。 2. **频繁触发 OOM Killer** - Linux 内核在内存耗尽时会强制终止占用内存大的进程(日志路径:`/var/log/messages` 或 `dmesg`)。 - 通过 `grep -i 'oom' /var/log/syslog` 搜索 OOM 记录。 3. **内存使用率持续高位** - 物理内存使用率(`used/(total)`) 长期超过 90%,且 `available` 内存极低。 4. **服务异常崩溃** - 数据库(如 MySQL)、Java 应用等因申请不到内存崩溃,日志中可能报错 `Cannot allocate memory`。 --- ### **三、排查与解决方案** #### **1. 临时缓解** - **释放缓存**(Linux): ```bash echo 1 > /proc/sys/vm/drop_caches # 释放页面缓存(谨慎操作) ``` - **终止异常进程**:通过 `kill` 或 `systemctl` 结束占用内存过高的进程。 - **增加 swap 空间**(仅临时应急,性能差)。 #### **2. 长期优化** - **升级硬件**:增加物理内存。 - **优化应用程序**:减少内存泄漏,调整 JVM 堆大小(Java 应用),优化查询(数据库)。 - **调整系统参数**: - 修改 `vm.swappiness`(降低 swap 使用倾向,默认值 60)。 - 限制进程内存(如通过 `cgroup`)。 #### **3. 监控与告警** - 设置内存使用率、swap 使用量的监控告警(如阈值超过 80% 触发通知)。 --- ### **四、注意事项** - **区分缓存(Cache)和实际占用**:Linux 会利用空闲内存缓存磁盘数据,这部分内存可快速释放,因此 `available` 比 `free` 更关键。 - **结合其他指标**:内存不足可能导致 CPU I/O 等待(`wa`%)升高,需综合判断。 --- 通过以上方法,可以快速定位内存问题并采取相应措施。如果内存不足是常态,建议优先优化程序或扩容硬件。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值