內(nèi)存出現(xiàn)故障 如何檢修
前沿拓展:
1、問題背景
我的博客網(wǎng)站https://blog.verysu.com,有興趣的可以訪問下。
最近服務(wù)器到期等因素,進行了遷移。租了其它的外國廠商,但是由于資費問題,購買了1.5G 內(nèi)存的服務(wù)器(現(xiàn))。因為原本用慣了4G內(nèi)存的服務(wù)器(原),現(xiàn)在壓縮成這樣,似乎不太能支持我的使用,囧!
現(xiàn)在就來說下blog服務(wù)分配的內(nèi)存情況:
原:4G 內(nèi)存,分配給blog,1.5G。
現(xiàn):1.5G內(nèi)存,分配給blog,500M。
由于此次調(diào)整,原本以為資源需求壓力會更大。實際上應(yīng)該不會,仔細想想,blog也沒多少內(nèi)容的。那么根據(jù)此次調(diào)整之后,已經(jīng)出現(xiàn)了2次OutOfMemoryError了。
由于JVM參數(shù)配置有加上XX:+HeapDumpOnOutOfMemoryError,所以出現(xiàn)OutOfMemoryError時會將堆棧輸出到指定的文件,這樣可以方便以后排查問題。
OS:CentOS7
Web容器:Tomcat 8
ORM:Hibernate3
數(shù)據(jù)庫:MySQL5
2、問題解決過程
2.1 診斷排查出現(xiàn)內(nèi)存泄漏對象
這個文件占用了差不多535M,說明里面的對象占用空間很大。這里我使用了MAT工具來排查。
1)Histogram (可以查看每個類的實例(即對象)的數(shù)量和大小)
通過Histogram圖,我們初步看出,實際上跟我們自己的代碼好像是沒有關(guān)系,因為這里沒找到我們對應(yīng)的包名和類名。不過可以看到一些疑惑就是Tomcat和mysql相關(guān)的類占用了很大內(nèi)存。
2)Dominator Tree(列出Heap Dump中處于活躍狀態(tài)中的最大的幾個對象,默認按 retained size進行排序)
從這里可以更加明確是哪些對象占用了大部分資源了,似乎也是跟Tomcat和mysql有關(guān)。
3)Top Consumer(按類、類加載器和包分別進行查詢,并以餅圖的方式列出最大的幾個對象)
通過上面這個餅圖,我們更加明確的是哪些對象占用了大部分資源。其它一些視圖這里就不展開了。
小結(jié):上面MAT的各種視圖表明,并不是說占用資源大的對象是就是內(nèi)存泄漏的罪魁禍首,它這里只是做了個統(tǒng)計,方便你觀察和發(fā)現(xiàn)問題,只是提示你可能這些對象存在泄漏的可能性。
2.2 診斷排查占用大資源內(nèi)因
由上面的圖中,我從TaskThread這個類入手:
發(fā)現(xiàn)主要占用的資源在StatefulPersistenceContext這個類,很明顯這個是Hibernate持久化相關(guān)的。
查看下類的注釋,大致意思是:
PersistenceContext表示Hibernate正在跟蹤的持久化“內(nèi)容”的狀態(tài)。這包括持久實體、集合以及生成的代理。
SessionImpl和PersistentContext之間應(yīng)該是一對一的對應(yīng)關(guān)系。SessionImpl使用PersistentContext來跟蹤其上下文的當前狀態(tài)。事件監(jiān)聽器使用PersistentContext來執(zhí)行處理。
因為Hibernate的一級緩存就是在Session層面上,所以StatefulPersistenceContext跟一級緩存有關(guān)系,網(wǎng)上有些資料也有說StatefulPersistenceContext存在問題可能造成內(nèi)存泄漏等原因。
可以在使用完Session時進行clear清除。這樣就能防止占用過大資源,但是,使用一級緩存是能夠大大的增強性能,如果這么做的話,似乎有違背Hibernate的設(shè)計初衷,因此,這里我們不能采取這種做法。
繼續(xù)往下挖,看這里面存放的是具體什么對象吧!
從這里可以看出,持久化的主要對象實體是ShareArticle,并且有1706個實體之多!~,這里只是TaskThread這個線程所持有這么多的實體,要知道下面還有幾個大對象TaskThread,里面也是有包含這些的,所以不僅僅1千個多實體。
2.3 找出問題根源(“真兇”)
看到這個實體的每個字段,才知道問題出現(xiàn)在哪!這張表有一個content字段,類型是mediumtext,存放文章內(nèi)容。所以一旦加載到內(nèi)存里,自然的需要占用大部分資源了。
找到問題的點在哪了,接下來就得看怎么優(yōu)化,畢竟在資源急缺的我,需要優(yōu)化下當前的服務(wù)了。
2.4 解決問題,優(yōu)化!優(yōu)化!
2.4.1 優(yōu)化之一:查詢不返回content字段
特別是哪些查詢列表相關(guān)的。這能大大的減少占用內(nèi)存。因為有些查詢List結(jié)果實際上是沒有使用到content字段,再次查詢出來也是一種浪費。
說下這個過程吧,由于使用的是Hibernate,雖說有其優(yōu)點,但是使用起來極其不靈活!在公司用慣了Mybatis,才知道Mybatis的好,哈哈!
2.4.2 優(yōu)化之二:只查詢需要的字段
在查詢當前文章的上下文時,基本上也是不用用到content字段,這里只需要返回id和title,即可。其實跟上面2.4.1的類似。
2.4.3 優(yōu)化之三:延遲加載指定字段
我們知道,Hibernate在一對多、多對多等關(guān)系中,是支持延遲加載的。查資料發(fā)現(xiàn)Hibernate3也能支持指定字段進行延遲加載,在需要的時候再次去查詢數(shù)據(jù)庫指定的字段再返回。
所以就動手干!但是也遇到使用時出現(xiàn)不生效,資料表明需要再次使用字節(jié)碼進行增強才能正常使用。具體操作可以看下下面這篇文字:https://blog.verysu.com/article/414
小結(jié):經(jīng)過上面的優(yōu)化,服務(wù)再也不會出現(xiàn)OutOfMemeryError了,而且資源占用也大幅度降低。
3、總結(jié)(經(jīng)驗與優(yōu)化)
1)針對占用資源多的,是否能夠不存在數(shù)據(jù)庫,比如生成靜態(tài)HTML文件,訪問的時候直接包含在頁面直接返回,這樣能快速返回,占用內(nèi)存少,提升性能。
2)針對大字段(占用資源大),沒用到時不返回。
3)只返回需要的字段,在SQL優(yōu)化的上必有,這樣也能提升mysql的吞吐量,也不會浪費資源。
4)如果追求靈活性,ORM建議使用mybatis,畢竟互聯(lián)網(wǎng)公司基本用它。Hibernate更適合在企業(yè)系統(tǒng)里面使用。
5)如果已經(jīng)使用了Hibernate了,可以增加字段延遲加載機制,進而在需要的時候再去查詢。
好了,為了寫這篇文章,花了兩個多小時,覺得不錯的話,點個贊唄^_^!
推薦工具1:
MAT:Eclipse Memory Analyzer 下載地址:
http://www.eclipse.org/mat/
推薦工具2:
IBM HeapAnalyzer 下載地址:
https://www.ibm.com/developerworks/community/groups/service/html/communityview?communityUuid=4544bafec7a2455f9d43eb866ea60091
參考資料:
Java程序內(nèi)存分析:使用mat工具分析內(nèi)存占用
https://www.cnblogs.com/AloneSword/p/3821569.html
Shallow Heap 和 Retained Heap的區(qū)別
https://blog.csdn.net/a740169405/article/details/53610689
Shallow heap & Retained heap
https://www.jianshu.com/p/0deac3af0f45
Java堆:Shallow Size和Retained Size
https://blog.csdn.net/iteye_18480/article/details/82514130
Hibernate 一級緩存導(dǎo)致某保險公司核心系統(tǒng)Weblogic中間件內(nèi)存溢出的故障診斷https://blog.csdn.net/zhouleiblog/article/details/82834331
Hibernate 一級緩存的陷阱
https://www.cnblogs.com/hyl8218/p/5076338.html
PS:如果上面的鏈接點擊不了,可以點擊閱讀原文進行查看。
歡迎關(guān)注Wx公眾hao:搬運工來架構(gòu)。更多干貨等你來~
拓展知識:
- 寧波市燃氣灶維修(寧波萬家樂燃氣灶維修)12-04
- 1電視頻道沒了怎么恢復(fù)(快速解決方法)
- 2海信42k11p怎么折開(海信42K11P:全方位展示超清畫質(zhì))
- 3Fardior燃氣灶售后維修電話號碼查詢(Fardior燃氣灶售后維修電話查詢)
- 4艾木歐防盜門沒電打不開怎么辦(艾木歐防盜門沒電無法啟動?解決方法總結(jié))
- 5ENS指紋鎖售后熱線(ENS指紋鎖售后熱線-專業(yè)解決您的問題)
- 6打電話顯示關(guān)機是什么原因(如何解決手機無法接通問題)。
- 7v500hk1 cs5故障維修(v500hk1 cs5故障維修指南)
- 8創(chuàng)維液晶電視的遙控器怎么調(diào)試(創(chuàng)維電視遙控器調(diào)試指南)
- 9林內(nèi)空氣能售后服務(wù)官網(wǎng)熱線(林內(nèi)空氣能售后服務(wù)官網(wǎng)熱線)
- 10朝友精工保險柜24小時售后電話(朝友精工保險柜24小時售后電話 - 完善24小時保
-
貼片代碼怎么看(深入解讀貼片代碼:洞悉世界編碼秘密)
2025-06-07
-
怎么拆彩電顯像管管座(拆解彩電顯像管管座技巧——30字以內(nèi))
2025-06-07
-
壁掛爐一天多少方氣(壁掛爐每天消耗幾方氣能?)
2025-06-07
-
海歌壁掛爐官網(wǎng)(海歌壁掛爐:讓溫暖環(huán)繞你)
2025-06-07
-
德能空氣能故障代碼e5(空調(diào)故障代碼E5的原因與解決方法)
2025-06-07


