書上P39java
不斷地建立對象, 並且保證建立的這些對象不會被回收便可(讓GC Root可達).學習
/** * 堆內存溢出demo * VM Options: -Xms6m -Xmx6m */ public class HeapOOM { static class OOMObejct { } public static void main(String[] args) { List<OOMObejct> list = new ArrayList<>(); while (true) { list.add(new OOMObejct()); } } }
會內存溢出, 輸出結果以下:atom
若是是用下面這段代碼的話, 是不會內存溢出的. 由於有GC. 每次new 的 Object在下次for循環中都退出了做用域, 虛擬機棧再也不持有對象的引用. 因此會被GC掉. 不會溢出.操作系統
/** * 堆內存溢出demo * VM Options: -Xms6m -Xmx6m */ public class HeapOOM { static class OOMObejct { } public static void main(String[] args) { while (true) { new OOMObejct(); } } }
visualVM的堆內存圖以下:線程
/** * 棧內存溢出demo * VM Options: -Xms6m -Xmx6m */ public class StackOverflow { private int stackDepth; private void stackLeak() { stackDepth++; stackLeak(); } public static void main(String[] args) { StackOverflow oom = new StackOverflow(); try { oom.stackLeak(); } catch (Throwable e) { System.out.println(oom.stackDepth); System.err.println(e.toString()); } } }
輸出結果以下(下面部分結果可能根據機器環境不一樣而不一樣): 3d
import java.util.concurrent.atomic.AtomicInteger; /** * 建立線程致使的內存溢出demo * VM Options: -Xms6m -Xmx6m */ public class CreateThreadOOM { static AtomicInteger counter = new AtomicInteger(0); public static void main(String[] args) { while (true) { new Thread(() -> { try { System.out.println(counter.incrementAndGet()); Thread.sleep(Integer.MAX_VALUE); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } } }
輸出結果以下(下面部分結果可能根據機器環境不一樣而不一樣): 對象
這段代碼我這裏沒有運行出書上的效果...blog
書上的意思應該是, 設定了直接內存大小最大爲10M後, 繼續申請的話, 就會報異常..內存
在我電腦上, 雖然也設置了MaxDirectMemorySize=10m , 可是這玩意硬生生地申請了10G的虛擬內存也沒停下, 最後被操做系統強制中止了.....(運行了幾回電腦都快沒電了)作用域
import sun.misc.Unsafe; import java.lang.reflect.Field; /** * VM Options: -Xms6m -Xmx6m -XX:MaxDirectMemorySize=10m */ public class DirectMemoryOOM { private static final int _1MB = 1024 * 1014; public static void main(String[] args) throws IllegalAccessException, InterruptedException { Field unsafeFile = Unsafe.class.getDeclaredFields()[0]; unsafeFile.setAccessible(true); Unsafe unsafe = (Unsafe) unsafeFile.get(null); while (true) { unsafe.allocateMemory(_1MB); Thread.sleep(10); } } }