Java 出現內存溢出的定位以及解決方案


在上一節中Java虛擬機內存分布   說了Java虛擬機中分為五個區域,而且也知道了在Java程序計數器區域不會出現OOM(OutOfMemeryError),那么以下就對除了程序計數器以外的四個區域出現OOM的原理以及解決方案進行解說。


1.Java虛擬機棧與本地方法棧

棧的大小控制參數時 -Xss。

Java虛擬機在棧中定義了兩種異常,StrackOverFlowError和OutOfMemeryError。當請求棧的深度大於java虛擬機所同意的最大深度則拋出StrackOverFlowError;假設Java虛擬機在棧擴展時。沒有申請到足夠的空間時,則拋出OutOfMemeryError。

StrackOverFlowError:Java虛擬機在執行中,調用方法時,都要創建棧幀,當棧的空間不夠時就會產生StrackOverFlowError。那么相應的解決方法就僅僅能是調節-Xss參數,或者降低方法的調用,減小棧幀的大小兩種方式。

OutOfMemeryError:在棧上出現OOM通常是多線程的情形。

首先咋們解析一下棧使用的空間能夠有多大,拿32位操作系統來舉例。 最大內存2G - Xmx(最大堆容量)- MaxPermSize(最慷慨法區容量)- 虛擬機本身耗費的內存和程序計數器使用的內存。

剩下的內存就是棧能夠使用的空間,當Xss配置的參數一定時,那么在不斷的創建線程過程中。遇到不能申請到棧空間的時候就會拋出OOM。那么相應的解決方案就是,調節-Xss參數減少棧大小,或者調節-Xmx以及MaxPermSize的大小擴大留給棧的空間。


2.方法區內存溢出

方法區的大小通過-PermSize和-MaxPermSize控制。


由於類常量和執行時常量也存儲在方法區中,所以執行時常量過多也可導致方法區的OOM,可是沒有直接控制常量池大小的參數,僅僅能通過-PermSize和-MaxPermSize來間接控制。

在Spring以及Hibernate。Mybatis中都會使用GeneratedConstructorAccessor、動態代理以及CGLib字節碼增強技術的等動態生成類,那么就須要強大的方法區來支撐。


3.堆內存的溢出

堆內存的溢出比較復雜,須要調節GC等多種參數,我們在后面的章節中會進行解說。



免責聲明!

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



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