Java内存溢出和内存泄露后怎么解决
1.首先這里先說一下內存溢出和內存泄露的區別:
內存溢出 out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;比如申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。
內存泄露 memory leak,是指程序在申請內存后,無法釋放已申請的內存空間,一次內存泄露危害可以忽略,但內存泄露堆積后果很嚴重,無論多少內存,遲早會被占光。
memory leak會最終會導致out of memory!
2.我們這里做一個內存溢出的例子
/*** VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError* @author Administrator**/public class TestDump {static class OOB {}public static void main(String[] args) {List<OOB> list = new ArrayList<OOB>();while (true) {list.add(new OOB());}}}其中-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError是需要加的JVM啟動參數
-Xms20m將堆的最小值設置為20MB,-Xmx20m將堆的最大值設置為20MB,當設置一樣時即可避免堆自動擴展。
-XX:+HeapDumpOnOutOfMemoryError可以讓虛擬機在內存溢出時Dump當前的內存堆轉儲快照以便事后進行分析。
運行結果:
java.lang.OutOfMemoryError: Java heap space Dumping heap to java_pid6256.hprof ... Heap dump file created [27904625 bytes in 0.098 secs] Exception in thread "main" java.lang.OutOfMemoryError: Java heap spaceat java.util.Arrays.copyOf(Arrays.java:2245)at java.util.Arrays.copyOf(Arrays.java:2219)at java.util.ArrayList.grow(ArrayList.java:242)at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:216)at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:208)at java.util.ArrayList.add(ArrayList.java:440)at com.webservie.TestDump.main(TestDump.java:18)異常信息java.lang.OutOfMemoryError: Java heap space。解決該區域問題,一般先通過內存印象分析工具(如Eclipse Memory Analyzer)對Dump出來的堆轉儲快照進行分析,重點是確認內存中的對象是否是必要的,
要就是先要分清楚到底是出現了內存泄露還是內存溢出。
java_pid6256.hprof就是生成的快照,可以在類所在的工程根目錄下找到。
打開該快照文件,如圖所示:
如果是內存泄露,可進一步通過工具查看泄露對象到GC Roots的引用鏈。于是就能找到泄露對象是通過怎樣的路徑與GC Roots相關聯并導致垃圾收集器無法自動回收它們的。
掌握了泄露對象的類型信息及GC Roots引用鏈的信息,就可以比較準確的定位出泄露代碼的位置。
如果不存在泄露,就是內存中的對象確實都還必須存活著,就應該檢測虛擬機的堆參數(-Xmx和-Xms),與機器物理內存對比,看看是否可以調大,從代碼上檢查是否存在某些
對象生命周期過長、持有狀態時間過長的情況,嘗試減少程序運行期的內存消耗。
?
轉載于:https://www.cnblogs.com/feiyangbahu/p/10362019.html
總結
以上是生活随笔為你收集整理的Java内存溢出和内存泄露后怎么解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx 配置两个域名
- 下一篇: Java算法面试题 一个顺子带一对