jvm中有哪些内存区域会发生内存溢出
1、方法區溢出
第一種原因:上線的時候MetaSpace區域直接用默認的參數,即根本不設置其大小,這會導Meta
Space區域可能才幾十M而已或者設置的比較小,此時對于一個稍微大型系統,因為他有很多自己的類,還依賴了很多外部jar包的類,MetaSpace空間很容易不夠的。
第二種原因:就是很多人開發系統代碼都會用一些cglib之類的技術動態生成一些類,一旦代碼沒有控制好,導致生成的類過多的時候,就很容易MetaSpace給塞滿,進而引起內存溢出。
2、虛擬機棧/本地方法棧溢出
(1)StackOverflowError:當線程請求的棧的深度大于虛擬機所允許的最大深度,則拋出StackOverflowError,簡單理解就是虛擬機棧中的棧幀數量過多(一個線程嵌套調用的方法數量過多)時,就會拋出StackOverflowError異常。最常見的場景就是方法無限遞歸調用。
(2)OutOfMemoryError:如果虛擬機在擴展棧時無法申請到足夠的內存空間,則拋出 OutOfMemoryError。
虛擬機中可以供棧占用的空間≈可用物理內存 - 最大堆內存 - 最大方法區內存,比如一臺機器內存為 4G,系統和其他應用占用 2G,虛擬機可用的物理內存為 2G,最大堆內存為 1G,最大方法區內存為 512M,那可供棧占有的內存大約就是 512M,假如我們設置每個線程棧的大小為 1M,那虛擬機中最多可以創建 512個線程,超過 512個線程再創建就沒有空間可以給棧了,就報 OutOfMemoryError 異常了。
3、堆內存溢出
(1)內存中加載的數據過多如一次從數據庫中取出過多數據;集合對對象引用過多且使用完后沒有清空;代碼中存在死循環或循環產生過多重復對象;堆內存分配不合理;網絡連接問題、數據庫問題等。
(2)系統承載高并發請求,因為請求量過大,導致大量的對象都是存活的,所以要放入新的對象放不下了,此時就會引起內存溢出系統崩潰;
(3)系統有泄漏的問題,就是莫名其妙產生了很多對象,結果對象都是存活的,沒有及時取消他們的引用,導致觸發GC還是無法回收,此時只能引發內存溢出,因為實在是放不下更多的對象了。
4、本機直接內存溢出
本機直接內存(DirectMemory)并不是虛擬機運行時數據區的一部分,也不是 Java 虛擬機規范中定義的內存區域,但 Java 中用到 NIO 相關操作時(比如 ByteBuffer 的 allocteDirect 方法申請的是本機直接內存),也可能會出現內存溢出的異常
總結
以上是生活随笔為你收集整理的jvm中有哪些内存区域会发生内存溢出的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么不要使用finalize方法
- 下一篇: 堆空间大小怎么配置,各区域怎么划分