經(jīng)驗(yàn)不在于年限,在于積累---專注互聯(lián)網(wǎng)軟件開發(fā)

          把工作當(dāng)事業(yè)做,把項(xiàng)目當(dāng)作品做!

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            55 Posts :: 0 Stories :: 66 Comments :: 0 Trackbacks

          公告

          本博文章除非特別說明,都是原創(chuàng)作品。歡迎各位轉(zhuǎn)載,但請注明出處,謝謝!hankchen:117744585@qq.com 微博地址:http://t.qq.com/hankchen2008

          常用鏈接

          留言簿(4)

          我參與的團(tuán)隊(duì)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          前一篇介紹了線上應(yīng)用故障排查之一:高CPU占用,這篇主要分析高內(nèi)存占用故障的排查。

          搞Java開發(fā)的,經(jīng)常會(huì)碰到下面兩種異常:

          1、java.lang.OutOfMemoryError: PermGen space

          2、java.lang.OutOfMemoryError: Java heap space

          要詳細(xì)解釋這兩種異常,需要簡單重提下Java內(nèi)存模型。

          (友情提示:本博文章歡迎轉(zhuǎn)載,但請注明出處:hankchen,http://www.aygfsteel.com/hankchen

          Java內(nèi)存模型是描述Java程序中各變量(實(shí)例域、靜態(tài)域和數(shù)組元素)之間的關(guān)系,以及在實(shí)際計(jì)算機(jī)系統(tǒng)中將變量存儲(chǔ)到內(nèi)存和從內(nèi)存取出變量這樣的低層細(xì)節(jié)。

          在Java虛擬機(jī)中,內(nèi)存分為三個(gè)代:新生代(New)、老生代(Old)、永久代(Perm)。

          (1)新生代New:新建的對象都存放這里

          (2)老生代Old:存放從新生代New中遷移過來的生命周期較久的對象。新生代New和老生代Old共同組成了堆內(nèi)存。

          (3)永久代Perm:是非堆內(nèi)存的組成部分。主要存放加載的Class類級(jí)對象如class本身,method,field等等。

          如果出現(xiàn)java.lang.OutOfMemoryError: Java heap space異常,說明Java虛擬機(jī)的堆內(nèi)存不夠。原因有二:

          (1)Java虛擬機(jī)的堆內(nèi)存設(shè)置不夠,可以通過參數(shù)-Xms、-Xmx來調(diào)整。

          (2)代碼中創(chuàng)建了大量大對象,并且長時(shí)間不能被垃圾收集器收集(存在被引用)。

          如果出現(xiàn)java.lang.OutOfMemoryError: PermGen space,說明是Java虛擬機(jī)對永久代Perm內(nèi)存設(shè)置不夠。

          一般出現(xiàn)這種情況,都是程序啟動(dòng)需要加載大量的第三方j(luò)ar包。例如:在一個(gè)Tomcat下部署了太多的應(yīng)用。

           

          從代碼的角度,軟件開發(fā)人員主要關(guān)注java.lang.OutOfMemoryError: Java heap space異常,減少不必要的對象創(chuàng)建,同時(shí)避免內(nèi)存泄漏。

          現(xiàn)在以一個(gè)實(shí)際的例子分析內(nèi)存占用的故障排查。

          2G19({7(0}N(FIL09LH175N

          通過top命令,發(fā)現(xiàn)PID為9004的Java進(jìn)程一直占用比較高的內(nèi)存不釋放(24.7%),出現(xiàn)高內(nèi)存占用的故障。

          想起上一篇線上應(yīng)用故障排查之一:高CPU占用介紹的PS命令,能否找到具體是哪個(gè)的線程呢?

          ps -mp 9004 -o THREAD,tid,time,rss,size,%mem

          1

          遺憾的是,發(fā)現(xiàn)PS命令可以查到具體進(jìn)程的CPU占用情況,但是不能查到一個(gè)進(jìn)程下具體線程的內(nèi)存占用情況。

           

          只好尋求其他方法了,幸好Java提供了一個(gè)很好的內(nèi)存監(jiān)控工具:jmap命令

          jmap命令有下面幾種常用的用法:

          ?jmap [pid]

          ?jmap -histo:live [pid] >a.log

          ?jmap -dump:live,format=b,file=xxx.xxx [pid]

          用得最多是后面兩個(gè)。其中,jmap -histo:live [pid] 可以查看當(dāng)前Java進(jìn)程創(chuàng)建的活躍對象數(shù)目和占用內(nèi)存大小。

          jmap -dump:live,format=b,file=xxx.xxx [pid] 則可以將當(dāng)前Java進(jìn)程的內(nèi)存占用情況導(dǎo)出來,方便用專門的內(nèi)存分析工具(例如:MAT)來分析。

          這個(gè)命令對于分析是否有內(nèi)存泄漏很有幫助。具體怎么使用可以查看本博的另一篇文章:利用Eclipse Memory Analyzer Tool(MAT)分析內(nèi)存泄漏

           

          這里詳細(xì)介紹下jmap -histo:live [pid] 命令:

          1

          從上圖可以看出,int數(shù)組、constMethodKlass、methodKlass、constantPoolKlass都占用了大量的內(nèi)存。

          特別是占用了大量內(nèi)存的int數(shù)組,需要仔細(xì)檢查相關(guān)代碼。

           

          最后,總結(jié)下排查內(nèi)存故障的方法和技巧有哪些:

          1、top命令:Linux命令??梢圆榭磳?shí)時(shí)的內(nèi)存使用情況。  

          2、jmap -histo:live [pid],然后分析具體的對象數(shù)目和占用內(nèi)存大小,從而定位代碼。

          3、jmap -dump:live,format=b,file=xxx.xxx [pid],然后利用MAT工具分析是否存在內(nèi)存泄漏等等。

          (友情提示:本博文章歡迎轉(zhuǎn)載,但請注明出處:hankchen,http://www.aygfsteel.com/hankchen

          posted on 2012-05-09 20:21 hankchen 閱讀(13005) 評論(2)  編輯  收藏 所屬分類: 工作感悟

          Feedback

          # re: 線上應(yīng)用故障排查之二:高內(nèi)存占用 2015-08-24 09:14 zhm
          ps -mp 9004 -o THREAD,tid,time,rss,size,%mem
          你上面pid是9004,下面的pid 2809從哪里來?
          jmap -histo:live 2809|head -n 100  回復(fù)  更多評論
            

          # re: 線上應(yīng)用故障排查之二:高內(nèi)存占用 2015-12-22 17:55 路人
          @zhm
          上面是PID下面是[pid]  回復(fù)  更多評論
            

          主站蜘蛛池模板: 英山县| 绥宁县| 长顺县| 洪泽县| 平和县| 句容市| 乌恰县| 通城县| 临漳县| 上犹县| 文山县| 滦平县| 石城县| 昌都县| 志丹县| 洪泽县| 开原市| 饶阳县| 肃宁县| 拜城县| 蛟河市| 深泽县| 特克斯县| 淮阳县| 怀远县| 论坛| 房山区| 息烽县| 婺源县| 乌鲁木齐县| 台江县| 孝感市| 曲阜市| 石景山区| 夹江县| 衢州市| 景谷| 宁乡县| 大城县| 桦甸市| 宁安市|