當虛擬機申請不到內存空間的時候,會報堆內存溢出: OutOfMemoryError:java heap space。java
常見的緣由: http://outofmemory.cn/c/java-...
我測試到時候,運行在 16G 內存的機器上。JVM 堆內存 默認爲物理內存的1/4,即 16 * 1/4 = 4G
數據庫
JDK 8的 JVM 在 JDK 7 的基礎上從堆內存中移除了 永久代(Perm Generation),替換爲了堆內存以外的 元空間(Metaspace),元空間是堆外直接內存,不受堆內存的限制,只受物理內存的限制,能夠提供更大的空間。
OutOfMemoryError 異常的常見緣由:數組
解決方法jvm
/**java堆溢出實例 * 原理:java的堆是用來存放對象實例的,因此咱們只要作到如下三點就可使堆溢出: * 一、限制堆的大小,不可擴展 * 二、不斷新建對象 * 三、保持對象存活不被回收 * 對應的,咱們須要: * 一、改變JVM的啓動參數,將堆的最小值和最大值設成同樣,這樣就能夠避免堆自動擴展(其實不同也能夠) * 二、不斷產生對象 * 三、使用一個List來保存對象,保持對象存活 * * JVM配置參數: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError * */ public class HeapOom { public static void main(String[] args) { // 此list實例會存放在堆內存中 List<byte[]> list = new ArrayList<>(); int i = 0; boolean flag = true; while (flag) { try { i++; // 每次增長一個1M大小的數組對象 list.add(new byte[1024 * 1024]); } catch (Throwable e) { // catch 捕獲的是 Throwable,而不是 Exception。由於 OutOfMemoryError 不屬於 Exception 的子類。 e.printStackTrace(); flag = false; // 記錄次數 System.out.println("count=" + i); } } // 不讓進程結束,便於使用分析工具來查看內存狀況 try { Thread.sleep(24 * 60 * 60 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
使用的 java 1.8.0_171 版本:工具
$ java -version java version "1.8.0_171" Java(TM) SE Runtime Environment (build 1.8.0_171-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
報錯信息:測試
count=3316 java.lang.OutOfMemoryError: Java heap space at com.song.HeapOom.main(HeapOom.java:21)
運行結果代表,運行到 3316 次時,出現了堆內存溢出。因爲每次增長1M內存。粗略估計:程序大約使用3G內存時,出現了內存溢出狀況。ui
經過jmap或VisualVM 者工具能夠查看內存狀況:最後能夠看出,老年代內存使用狀況,大約使用了2709MB,使用率近100%。從而致使了 OutOfMemoryErrorspa
TIPS:下面查看內存時,因爲使用工具查看內存的時間不是同一時間,因此內存使用量有細微差異
$ jmap -heap 3428 Attaching to process ID 3428, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.66-b18 using thread-local object allocation. Parallel GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 4261412864 (4064.0MB) NewSize = 88604672 (84.5MB) MaxNewSize = 1420296192 (1354.5MB) OldSize = 177733632 (169.5MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 637009920 (607.5MB) used = 637009920 (607.5MB) free = 0 (0.0MB) 100.0% used From Space: capacity = 11010048 (10.5MB) used = 0 (0.0MB) free = 11010048 (10.5MB) 0.0% used To Space: capacity = 11010048 (10.5MB) used = 0 (0.0MB) free = 11010048 (10.5MB) 0.0% used PS Old Generation // 老年代內存使用狀況,大約使用了2709MB,使用率近100%(致使OutOfMemoryError) capacity = 2841116672 (2709.5MB) used = 2840991320 (2709.38045501709MB) free = 125352 (0.11954498291015625MB) 99.99558793198338% used 4955 interned Strings occupying 422328 bytes.