java 内存溢出 内存泄露_JVM——内存泄漏与内存溢出
1.內存溢出
1.1 什么是Java的內存溢出?
在Java程序運行的過程中,經常會碰到以下錯誤:java.lang.OutOfMemoryError。
通俗講,內存溢出是指程序在申請內存時,沒有足夠的內存空間供其使用,出現OutOfMemoryError。
1.2 產生原因?
簡單來講為以下兩點:
1. JVM內存過小
2. 產生過多的,沒有被回收的垃圾
以下討論主要基于JVM上不同內存區域的討論
1.3 Java堆溢出
Java堆是存放對象實例的地方,當我們不斷申請創建對象,并且保證這些對象始終可以從GC Roots可達,總容量就會觸及最大堆的容量限制而拋出內存溢出異常
例如以下代碼,將虛擬機的初始大小設為 20M ,并且不可變(將堆的最小值 -Xms 和 堆的最大值 -Xmx 設置為一樣可以避免Java堆自動擴展!)
public class OOM {
/*
-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
*/
static class OOMObject{
}
public static void main(String[] args){
List list = new ArrayList<>();
while(true){
list.add(new OOMObject());
}
}
}
解決方法
常規處理方法是通過內存映像分析工具對 Dump 出來的堆轉儲快照進行分析。
1.首先分析是內存泄漏還是內存溢出
2.如果是內存泄漏通過工具查看泄露對象到 GC Roots 的引用鏈,分析垃圾收集器無法回收他們的原因,進而定位到出現問題的代碼
3.如果不是內存泄漏,即對象都應該必須活著,就應該對比 JVM堆內存 和機器內存相比是否還有向上調整的空間;或者從代碼上檢查某些對象是否生命周期過長,持有狀態時間過長,存儲結構設計不合理等,盡量減少程序運行期間的內存消耗
1.4 虛擬機棧和本地方法棧溢出
1. 如果線程請求棧的深度大于虛擬機所允許的最大深度,將拋出 StackOverflowError 異常
2. 如果虛擬機的棧內存允許動態的擴展,當擴展棧的容量無法申請到足夠的內存的時候,將拋出’OutOfMemoryError’異常
解決方法
1.出現 StackOverflowError 異常時,會有明確錯誤堆棧可供分析,比較容易定位問題所在,例如遞歸沒有終止條件。棧深度大多數情況下到達1000-2000是沒有問題的,對于正常方法的調用,這個深度完全是夠用的。
2.但如果是因為建立過多線程導致內存溢出,在不能減少線程的數量的情況下,只能通過減少最大堆的容量或者減少棧的容量來獲取更多的線程!
1.5 方法區和運行時常量池溢出
由于在JDK 8 以后,永久代退出了歷史舞臺,元空間作為其替代者登場,即元空間使用的是直接內存,受限于本機物理內存的大小,不再容易拋出方法區的內存溢出。而在JDK 8 之前,方法區的實現永久代是會因為加載了大量的類(比如CG Lib字節碼技術)而拋出方法區內存溢出的,或者因為運行時常量池(JDK 6 還是屬于方法區的一部分,拋出的是方法區的內存溢出;而JDK7之后便移到Java堆上,拋出的是java的堆內存溢出)而拋出對應區域的內存溢出!
1.6 本機直接內存溢出
直接內存可以通過 -XX:MaxDirectMemorySize 參數來指定,若不指定則默認與堆的最大值保持一致。
由直接內存導致的內存溢出,一個明顯的特征就是在dump下的文件不會看到有明顯的異常情況,或者該文件很小,而程序又直接或者間接的使用了 Direct Memory ,就應該去考慮是否是本機直接內存溢出
2. 內存泄漏
Memory Leak,是指程序在申請內存后,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積后果很嚴重,無論多少內存,遲早會被占光。
在Java中,內存泄漏就是存在一些被分配的對象,這些對象有下面兩個特點:
首先,這些對象是可達的,即在有向圖中,存在通路可以與其相連;
其次,這些對象是無用的,即程序以后不會再使用這些對象。
如果對象滿足這兩個條件,這些對象就可以判定為Java中的內存泄漏,這些對象不會被GC所回收,然而它卻占用內存。
3.兩者聯系
內存泄露會最終會導致內存溢出。
相同點:都會導致應用程序運行出現問題,性能下降或掛起。
不同點:
1. 內存泄露是導致內存溢出的原因之一,內存泄露積累起來將導致內存溢出。
1. 內存泄露可以通過完善代碼來避免,內存溢出可以通過調整配置來減少發生頻率,但無法徹底避免。
本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
總結
以上是生活随笔為你收集整理的java 内存溢出 内存泄露_JVM——内存泄漏与内存溢出的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java for list i_Java
- 下一篇: java mvc mvp mvvm_一篇