Hibernate 一級緩存的陷阱


最近公司的應用經常報OOM,一開始我以為是公司業務數據太多,導致內存不夠,所以只是簡單的把容器的內存加大。撐了幾天后這個錯仍然被報出來。后來我仔 細分析過項目代碼后,沒有發現有任何引起內存泄漏的地方。百思不得其解,於是我決定在OOM異常發生的那刻將JVM內存堆導出來仔細分析,我在生產環境的某一台機器上加上了JVM啟動參數:“-XX:+HeapDumpOnOutOfMemoryError
    -XX:HeapDumpPath=/app/vas_platform/temp/” 然后等了一天,終於又報錯了,拿出堆文件用“Eclipse Memory Analyzer”打開分析,發現占用內存的地方居然有75%來自org.hibernate.engine.StatefulPersistenceContext(靠,這不科學啊!)
Hibernate <wbr>一級緩存的陷阱(轉)

 

后來查看各個StatefulPersistenceContext里面的內容發現里面保存存着多達幾十萬個實體對象,其中大部分都是比較大的對象(本身字段特別多而且還級聯了許多其它的實體一級接着一級的級聯), 心想為什么會這樣呢?一個請求過來->打開Session->處理完業務->關閉Session,沒問題啊而且所有頁面均沒有卡死的現 像,難道代碼里面有占用Session沒關的地方。於是仔細分析代碼終於被我發現問題了。我們的應用會定時啟動幾個quartz任務來處理復雜且影響頁面 響應時間的業務,這部分業務的業務數據是從數據庫查的,只有業務數據全都被處理完后這個quartz才會結束。

因為Hibernate的Session是帶有一級緩存的,每個經由Session查出來的對象會填充至一級緩存,以避免多次的數據庫仿問。當這幾個 quartz任務的業務數據較多的時候,就會有很多對象被填入一級緩存這樣一來持久化上下文中保存的對象越來越多。最終導致OOM.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM