標籤:java jvm oom
看到OOM的很多文章,然後自己也測試了下。每段程式都寫了OOM的原因。從java記憶體模型開始分析就行了。
估計也不是太難。就是用jconsole監控資源的時候,感覺不太舒服。
package com.oom;import java.util.ArrayList;import java.util.List;/* * 堆oom * 類的執行個體放到heap中,所以不斷建立類就可以測試出heap的oom了 * jconsole可以監控資源 * * Exception in thread "main" java.lang.OutOfMemoryError: Java heap space */public class HeapOOM {static class TestHeepObject{ }public static void main(String[] args) {List<TestHeepObject > heapList=new ArrayList<TestHeepObject>();while(true){heapList.add(new TestHeepObject()); }}}
package com.oom;import com.oom.HeapOOM.TestHeepObject;/* * stack outof erro * * 方法無限遞迴可以測試出 * 每個main方法啟動一個棧,然後不斷的遞迴方法進入棧(棧資訊儲存部分方法的返回點),直到stack滿發生sof異常 * * Exception in thread "main" java.lang.StackOverflowError */public class VmSOF {public static void main(String[] args) {new VmSOF().testSOF();}private void testSOF() {testSOF();}}
package com.oom;import java.util.ArrayList;/* * * 不斷增加常量到常量池出現OOM異常 * Exception in thread "main" java.lang.OutOfMemoryError: PermGen space */public class RuntimeConstantPoolOOM {public static void main(String[] args) {/*al引用到常量池,保證不被gc回收。因為現在部分商用的JVM在實現永久地區的時候會full gc了。 * 常量是儲存在堆中的永久區。 */ArrayList<String> al=new ArrayList<String>(); int i=0;while(true){al.add(String.valueOf(i++).intern()); //intern將字串遷移到常量池}}}
package com.oom;/* * 建立線程造成oom * 這個還是不要測試了。如果你的機器夠強筋,算我沒說~~~ * 話說我重啟了~~ * */public class CreateTheadOOM {private static void loop() {while(true){}}private void runThead() {while(true){ new Thread(new Runnable() {public void run() {loop();}}).start();}}public static void main(String[] args) {new CreateTheadOOM().runThead();}}
還有通java直接記憶體的oom和CGlib給方法區載入class造成的oom。
深入JVM的OOM