openjdk platform binary 内存_记一次内存溢出导致的生产事故
背景
因為同事的離職,半路被迫接手的一個可視化項目,使用ElasticSearch作為OLAP數(shù)據(jù)庫、Docker作為部署工具等,突然有一天項目現(xiàn)場環(huán)境出現(xiàn)JVM內(nèi)存溢出問題,被迫披掛上陣定位問題的原因
分析過程
top命令查看系統(tǒng)資源占有情況,cpu占用不高,內(nèi)存占用高,并且虛擬內(nèi)存高達16g
Tips:Java 程序由于自己維護堆的使用,導(dǎo)致調(diào)用 glibc 去管理內(nèi)存的次數(shù)較少。更糟的是 Java 8 開始使用 metaspace 原空間取代永久代,而元空間是存放在操作系統(tǒng)本地內(nèi)存中,那線程一多,每個線程都要使用一點元空間,每個線程都分配一個arena,每個都64MB,就會導(dǎo)致巨大的虛擬地址被分配。
free -h 查看內(nèi)存占有,buffer/cache占有很大,總內(nèi)存剩余7g
Tips:buffers是用來緩沖塊設(shè)備做的,它只記錄文件系統(tǒng)的元數(shù)據(jù)(metadata)以及 tracking in-flight pages,而cached是用來給文件做緩沖。更通俗一點說:buffers主要用來存放目錄里面有什么內(nèi)容,文件的屬性以及權(quán)限等等。而cached直接用來記憶我們打開過的文件和程序。
通過系統(tǒng)日志中的java.lang.OutOfMemoryError與系統(tǒng)資源占用情況基本定位是jvm內(nèi)存溢出造成的
進一步使用jdk自帶性能監(jiān)控工具查找原因
- jmap -heap 1 //查看堆內(nèi)存情況,無此命令參數(shù),因為該服務(wù)使用的是docker鏡像的openjdk導(dǎo)致缺失部分jdk完整工具支持
- jstat -gc 1 250 10 //查看垃圾回收gc狀態(tài)情況,新生代與老年代內(nèi)存基本耗盡,FullGC高達1200多次,但是未釋放成功
- jmap -histo:live 1 | head -n 100 //查看top前100的實例數(shù)量情況,再次受阻,報錯Unable to get pid
執(zhí)行jmap命令遇到的Unable to get pid可以采用的解決方案:
- 在docker run時加上 --init 參數(shù)
- 安裝Tini,使用tini作為入口進程,配置啟動java進程
接下來,我們使用Alibaba開源的診斷工具Arthas可視化工具排查問題(PS:如果大家對Arthas不了解,可以查看官方文檔)
下載arthas全量jar>拷貝到容器內(nèi)>成功啟動jar
docker cp 解壓絕對路徑 platform:/tmp/docker exec -it platform /bin/sh -c "cd /tmp/arthas; java -jar arthas-boot.jar"執(zhí)行dashboard查看資源占有情況
通過dashboard了解到資源已基本耗盡,線程執(zhí)行基本正常,最終需要通過導(dǎo)出dump文件分析內(nèi)存分布進行分析
執(zhí)行heapdump /tmp/dump.hprof導(dǎo)出dump文件,下載dump文件到本地,通過MAT工具進行分析
最終定位問題是因為項目中未正確使用緩存導(dǎo)致的
參考
mac下安裝MAT進行分析
Mac OS下MAT(Memory Analyzer Tool)安裝與啟動?blog.csdn.netopenjdk-alpine容器中的jvm如何執(zhí)行dump
openjdk-alpine容器中的jvm如何dump?www.crazy1984.com本文由博客群發(fā)一文多發(fā)等運營工具平臺 OpenWrite 發(fā)布總結(jié)
以上是生活随笔為你收集整理的openjdk platform binary 内存_记一次内存溢出导致的生产事故的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: just函数 python_在pytho
- 下一篇: lisp如何将度分秒转换为弧度_地学中常