linux-buff/cache过大导致内存不足-程序异常
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
問(wèn)題描述
Linux內(nèi)存使用量超過(guò)閾值,使得Java應(yīng)用程序無(wú)可用內(nèi)存,最終導(dǎo)致程序崩潰。即使在程序沒(méi)有掛掉時(shí)把程序停掉,系統(tǒng)內(nèi)存也不會(huì)被釋放。
找原因的過(guò)程
這個(gè)問(wèn)題已經(jīng)困擾我好幾個(gè)月了,分析過(guò)好多次都沒(méi)有找到原因,網(wǎng)上查了一下該問(wèn)題其他人也都遇到過(guò),不過(guò)并沒(méi)有什么好的解決方案,因?yàn)轫?xiàng)目一直沒(méi)有上線,每次當(dāng)內(nèi)存不足時(shí)導(dǎo)致程序崩潰都是重啟服務(wù)就好了,索性也就沒(méi)花太多的時(shí)間來(lái)找問(wèn)題。現(xiàn)在項(xiàng)目馬上上線了,不能在出現(xiàn)程序崩潰的情況了,況且還是前置系統(tǒng),更不能出現(xiàn)任何問(wèn)題。
最開(kāi)始一直認(rèn)為是程序的原因?qū)е聝?nèi)存泄漏,使用jdk自帶的jmap -F -dump:live,format=b,file=/usr/local/sztFront/logs/heapdump.bin命令輸出過(guò)幾次dump文件,通過(guò)MemoryAnalyzer分析,應(yīng)用程序沒(méi)有耗內(nèi)存過(guò)大的變量。后臺(tái)猜測(cè)是否日志輸出過(guò)多導(dǎo)致的,畢竟是前置系統(tǒng),每天的報(bào)文量特別大,日志能到達(dá)5,6個(gè)G。所以把日志接收?qǐng)?bào)文關(guān)了,日志大小馬上降下來(lái)了,每天200M。程序掛掉的時(shí)間變長(zhǎng)了,原來(lái)差不多一周就掛掉了,現(xiàn)在可以達(dá)到兩周左右才掛掉,還是不行,沒(méi)有沖根本上解決問(wèn)題。經(jīng)過(guò)在網(wǎng)上搜索各種相關(guān)的問(wèn)題,問(wèn)題出現(xiàn)在Cached的值過(guò)大,導(dǎo)致系統(tǒng)沒(méi)有可以再分配的內(nèi)存空間。Cached只要用來(lái)緩存文件的,經(jīng)常讀寫(xiě)的文件會(huì)被緩存到Cached中,可以增加讀寫(xiě)效率,該功能是Linux系統(tǒng)內(nèi)核提供的,從2.6.16以后的核心版本才提供,也就是老版的操作系統(tǒng),如紅旗DC 5.0、RHEL 4.x之前的版本都沒(méi)有。這就可以解釋為什么我的項(xiàng)目總掛掉了,我的項(xiàng)目主要就是處理文件的,所以接收和下載的文件會(huì)被緩存起來(lái),一直耗著內(nèi)存不釋放,即使把程序停掉也不會(huì)釋放內(nèi)存。最后找到了三條執(zhí)行,可以清理cached的內(nèi)存
三條指令:
sync
echo 1 > /proc/sys/vm/drop_caches
echo 2 > /proc/sys/vm/drop_caches
echo 3 > /proc/sys/vm/drop_caches
執(zhí)行完這三條指令后通過(guò)free -m命令查看,free可用內(nèi)存馬上增多,buff/cache列值變小,說(shuō)明內(nèi)存被釋放了,但是不能總是手動(dòng)的執(zhí)行這三條指令,所以最后寫(xiě)了一個(gè)shell腳本,開(kāi)啟Linux定時(shí)任務(wù)crond,每天早上檢查一次free內(nèi)存,當(dāng)小于4G時(shí)執(zhí)行這三條命令(注:系統(tǒng)內(nèi)容20G)。
注意:在執(zhí)行這三條命令之前一定要先執(zhí)行sync命令(描述:sync 命令運(yùn)行 sync 子例程。如果必須停止系統(tǒng),則運(yùn)行sync 命令以確保文件系統(tǒng)的完整性。sync 命令將所有未寫(xiě)的系統(tǒng)緩沖區(qū)寫(xiě)到磁盤(pán)中,包含已修改的 i-Node、已延遲的塊 I/O 和讀寫(xiě)映射文件)
解決方案(手動(dòng))
1. 修改/proc/sys/vm/drop_caches,釋放Slab占用的cache內(nèi)存空間(參考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.
注意:在執(zhí)行這三條命令前先執(zhí)行sync命令
解決方案(自動(dòng))
1、編寫(xiě)shell定時(shí)任務(wù)腳本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命令編輯當(dāng)前用戶(hù)的crontab
0 6 * * * /usr/local/tomcat/sztFileFront/bin/freemem.sh
定時(shí)任務(wù)編寫(xiě)參考:http://www.jb51.net/article/15008.htm
3、重啟crond服務(wù)
/sbin/service crond restart
4、查看crond服務(wù)是否重啟成功
/sbin/service crond status
最后,問(wèn)題解決。我設(shè)定的定時(shí)任務(wù)是每天早上6點(diǎn)執(zhí)行一次freemem.sh腳本
?
轉(zhuǎn)載于:https://my.oschina.net/u/3049601/blog/2990323
總結(jié)
以上是生活随笔為你收集整理的linux-buff/cache过大导致内存不足-程序异常的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 梦到亲人被雷劈了是什么意思
- 下一篇: Source Insight 创建工程(