日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一文學(xué)會核心服務(wù)OOM!

P0事故安排上了

原來以為內(nèi)存溢出這種事情只會發(fā)生在書本上,沒想到在我們生產(chǎn)環(huán)境發(fā)生了,而且是618,P0事故安排上了。先回顧一下內(nèi)存溢出排查的基本思路,然后再來復(fù)盤一下內(nèi)存溢出發(fā)生的原因

創(chuàng)新互聯(lián)建站是一家專注于網(wǎng)站設(shè)計、網(wǎng)站制作和成都服務(wù)器托管的網(wǎng)絡(luò)公司,有著豐富的建站經(jīng)驗和案例。

內(nèi)存溢出排查

我們先來了解一下Java堆的組成機構(gòu)。對于大多數(shù)應(yīng)用來說,Java堆(Java Heap)是Java虛擬機鎖管理的內(nèi)存中最大的一塊。Java堆是所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機啟動時創(chuàng)建。此內(nèi)存區(qū)域的唯一目的就是存放對象實例,幾乎所有的對象實例都在這里分配內(nèi)存

「堆的結(jié)構(gòu)如下」

「新生代老年代的具體劃分比例如下」

「分代的主要作用就是為了更高效的管理內(nèi)存」

內(nèi)存泄漏和內(nèi)存溢出是2個不同的概念

內(nèi)存泄漏:對象已經(jīng)不使用了,但是還占用著內(nèi)存空間,沒有被釋放 內(nèi)存溢出:堆空間不夠用了,通常表現(xiàn)為OutOfMemoryError,內(nèi)存泄漏通常會導(dǎo)致內(nèi)存溢出

使用Java VisualVM分析排查

「我們可以通過jdk自帶的jvisualvm命令來分析堆的使用情況」

我們寫一個程序,來演示內(nèi)存不斷增加的場景

 
 
 
 
  1. public class OomDemo {
  2.     private static final int NUM = 1024;
  3.     public static void main(String[] args) throws InterruptedException {
  4.         List list = Lists.newArrayList();
  5.         for (int i = 0; i < NUM; i++) {
  6.             TimeUnit.SECONDS.sleep(1);
  7.             list.add(new byte[NUM * NUM]);
  8.         }
  9.     }
  10. }

「命令行中執(zhí)行jvisualvm即可彈出圖形界面,我們可以連接到本機上的程序,也可以連接到遠(yuǎn)程機器,還可以分析生成快照文件等」。

可以清晰的看到堆空間在不斷上漲,用抽樣器分析一下內(nèi)存不斷上漲的源頭在哪里?

「好家伙,byte數(shù)組居然占用了這么多內(nèi)存」

如果此時你還看不出程序哪里有問題,到監(jiān)視這個Tab點擊堆Dump這個按鈕,會生成一個堆的快照,然后分析這個dump文件即可

byte數(shù)組實例很少,但是占用內(nèi)存很多,再看一下具體的引用

可以看到在ArrayList中。

最后推薦一個插件Visual GC,可以清晰的看到堆的使用情況以垃圾收集信息。

點擊工具選中插件即可

當(dāng)然你可以通過jmap命令生成heapdump文件,然后用其他工具分析

 
 
 
 
  1. jmap -dump:file=文件名字 進(jìn)程id

使用Eclipse Memory Analyzer分析

Java VisualVM只提供了一些基本的功能,堆中各種對象的大小和實例數(shù)。以上面的例子為例,你只能排查到ArrayList占用了大量的內(nèi)存,這個ArrayList在哪,你也不知道

所以我們一般不使用Java VisualVM來分析,而是使用Eclipse Memory Analyzer來分析

Eclipse Memory Analyzer下載地址:https://www.eclipse.org/mat/downloads.php

還是上面的程序,我們啟動時設(shè)置如下參數(shù),讓程序內(nèi)存溢出時自動生成Dump文件

 
 
 
 
  1. -Xmx30m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/peng

-Xmx30m:最大堆內(nèi)存為30m -XX:+HeapDumpOnOutOfMemoryError:當(dāng)JVM發(fā)生OOM時,自動生成DUMP文件。-XX:HeapDumpPath:指定文件路徑,例如:-XX:HeapDumpPath=${目錄}/java_heapdump.hprof。如果不指定文件名,默認(rèn)為:java_pid .hprof

生產(chǎn)環(huán)境一般都會配置堆溢出時自動生成DUMP文件圖片當(dāng)內(nèi)存溢出的時候自動生成了一個文件,java_pid28598.hprof

「用Eclipse Memory Analyzer打開這個文件,可以很清晰的看到總共使用的內(nèi)存,以及各個對象占用的內(nèi)存」,如下圖

總共使用的內(nèi)存為26.8M Thread對象占用了26M ZoneInfoFile對象占用了157.8KB 其他對象占用了696.7KB

點擊Leak Suspects按鈕查看具體的內(nèi)存泄露報告

分析出來有問題的部分只有一處(例子太簡單的緣故,很多時候會分析出來多處)

「main線程占用了97.21%的內(nèi)存空間」

「點擊標(biāo)紅按鈕,查看引用關(guān)系,可以很清晰的看到是由于main線程中ArrayList中放了26個byte數(shù)組造成的」

「另外可以很清晰的看到內(nèi)存溢出時代碼的執(zhí)行位置,排查問題非常方便」

事故復(fù)盤

先來看一下事故發(fā)生前和事故發(fā)生后JVM的情況,我們新生代用的是ParNew垃圾收集器,老年代用的是CMS垃圾收集器

13:00-13:10這段時間的情況,系統(tǒng)正常運行

每分鐘GC暫停時間(綠色部分是CMS,黃色部分是ParNew)

每分鐘GC次數(shù)和GC平均耗時(綠色部分是CMS,黃色部分是ParNew)

新生代和老年代的占用情況

「可以看到問題發(fā)生之前老年代已經(jīng)設(shè)置的不合理了,偏小了」。

14:00-14:10這段時間的情況,14:06系統(tǒng)內(nèi)存溢出

14:00活動開始,14:05之后每分鐘垃圾回收暫停的時間過長,都達(dá)到30s了

老年代垃圾回收的時間飆升

實在沒有可回收的了,最終老年代被占滿,內(nèi)存溢出

分析dump文件

運維配置了上面說的2個參數(shù),內(nèi)存溢出時生成了dump文件,用Eclipse Memory Analyzer打開分析一波

總共1.9G,ThreadPoolExecutor占用了918.8MB,我們來看看ThreadPoolExecutor這個線程池里面到底放了些啥

分析報告指出的第一個問題就是ThreadPoolExecutor里面的東西太大了,占了總內(nèi)存的47.45%了,點擊如下按鈕,查看引用鏈路

好家伙,線程池占用了900多m空間,里面用LinkedBlockingDeque存放待執(zhí)行的任務(wù)

「隊列的能存放的最大數(shù)量是10000,目前放了883個任務(wù),這個隊列的長度設(shè)置的也忒大了把!」

繼續(xù)點下去,就能看到隊列中存的具體對象,是個DTO??窗筒碌绞侵虚g件團隊將這個DTO放到線程池中

大概邏輯如上圖,中間件團隊會通過一個agent攔截應(yīng)用中方法的執(zhí)行,并將入?yún)⒑头祷刂荡蛴≡谌罩局校琭lume收集日志后給鏈路平臺,監(jiān)控平臺提供數(shù)據(jù)。

方法每執(zhí)行一次打印一次日志,但是日志的打印是異步化的,將參數(shù)和返回值封裝成任務(wù),放到線程池中執(zhí)行。由于618方法被高頻調(diào)用,而其中一類DTO對象很大(一個對象6,7m),任務(wù)一旦堆積,很快就是OOM?!敢驗殛犃械淖畲笾当辉O(shè)置為10000,但是當(dāng)放了883個任務(wù)的時候已經(jīng)OOM了」

本文轉(zhuǎn)載自微信公眾號「Java識堂」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Java識堂公眾號。


本文標(biāo)題:一文學(xué)會核心服務(wù)OOM!
當(dāng)前鏈接:http://www.dlmjj.cn/article/cdpgcdg.html