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

http://blog.csdn.net/u014740338/article/details/66975550


问题描述

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的官方文档):

[plain]  view plain  copy
  1. Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free.  
  2. To free pagecache:  
  3. * echo 1 > /proc/sys/vm/drop_caches  
  4. To free dentries and inodes:  
  5. * echo 2 > /proc/sys/vm/drop_caches  
  6. To free pagecache, dentries and inodes:  
  7. * echo 3 > /proc/sys/vm/drop_caches  
  8. 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.  
  9. This tunable was added in 2.6.16.  

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


解决方案(自动)

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

[plain]  view plain  copy
  1. #! /bin/sh  
  2. used=`free -m | awk 'NR==2' | awk '{print $3}'`  
  3. free=`free -m | awk 'NR==2' | awk '{print $4}'`  
  4. echo "===========================" >> /app/memory/logs/mem.log  
  5. date >> /app/memory/logs/mem.log  
  6. echo "Memory usage before | [Use:${used}MB][Free:${free}MB]" >> /app/memory/logs/mem.log  
  7. if [ $free -le 4000 ] ; then  
  8.                 sync && echo 1 > /proc/sys/vm/drop_caches  
  9.                 sync && echo 2 > /proc/sys/vm/drop_caches  
  10.                 sync && echo 3 > /proc/sys/vm/drop_caches  
  11.                 used_ok=`free -m | awk 'NR==2' | awk '{print $3}'`  
  12.                 free_ok=`free -m | awk 'NR==2' | awk '{print $4}'`  
  13.                 echo "Memory usage after | [Use:${used_ok}MB][Free:${free_ok}MB]" >> /app/memory/logs/mem.log  
  14.                 echo "OK" >> /app/memory/logs/mem.log  
  15. else  
  16.                 echo "Not required" >> /app/memory/logs/mem.log  
  17. fi  
  18. exit 1  

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

[plain]  view plain  copy
  1. 0 6 * * * /usr/local/tomcat/sztFileFront/bin/freemem.sh  

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


3、重启crond服务

[plain]  view plain  copy
  1. /sbin/service crond restart  

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

[plain]  view plain  copy
  1. /sbin/service crond status  



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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 系统中,buff/cache 是操作系统用来缓存磁盘数据的一种机制。当应用程序需要读取磁盘上的数据时,Linux 会先将这些数据缓存内存中,以提高磁盘读取速度。当应用程序需要使用内存时,缓存数据会被清除,将内存返还给应用程序使用。 如果 buff/cache 内存占用过高,有几种可能的解决办法: 1. 调整 vm.dirty_ratio 和 vm.dirty_background_ratio 参数 vm.dirty_ratio 指定了内存中脏数据所占的最大比例,默认值为 20,意味着当内存中脏数据占用超过 20% 时,系统会开始写入磁盘。vm.dirty_background_ratio 指定了内存中脏数据所占的最小比例,默认值为 10,意味着当内存中脏数据占用低于 10% 时,系统会开始写入磁盘。 可以通过修改这两个参数的值来调整 buff/cache 内存占用。例如,将 vm.dirty_ratio 和 vm.dirty_background_ratio 的值都设置为 5,则系统会更频繁地把脏数据写入磁盘,从而减少内存中的缓存数据。 2. 调整 swappiness 参数 swappiness 是一个控制系统将内存中的数据交换到交换空间的程度的参数。默认值为 60,意味着当内存使用率达到 60% 时,系统会开始把一些数据写入交换空间。可以通过修改 swappiness 的值来调整系统的交换行为,从而影响 buff/cache 内存占用。 例如,将 swappiness 的值设置为较低的 10,则系统会更倾向于保留内存中的缓存数据,从而减少交换行为,降低 buff/cache 内存占用。 3. 增加物理内存 如果系统中物理内存不足,buff/cache 内存占用就会相对较高。可以通过增加物理内存来减少 buff/cache 内存占用,从而提高系统的性能。 需要注意的是,增加物理内存并不是万能的解决办法,可能存在其他因素导致的 buff/cache 内存占用过高问题。在调整系统参数和增加物理内存之前,需要仔细分析系统的性能瓶颈和内存使用情况,找出问题的根本原因。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值