JVM學習筆記——垃圾回收篇( 四 )


// 相關配置信息:配置默認大?。?設置回收方法 , 顯示GC詳情,開啟FullGC前進行gc// -Xms20M -Xmx20M -Xmn10M -XX:+UseSerialGC -XX:+PrintGCDetails -verbose:gc -XX:-ScavengeBeforeFullGC/*首先我們展示不添加內存的狀況*/package cn.itcast.jvm.t2;import java.util.ArrayList;public class Demo2_1 {private static final int _512KB = 512 * 1024;private static final int _1MB = 1024 * 1024;private static final int _6MB = 6 * 1024 * 1024;private static final int _7MB = 7 * 1024 * 1024;private static final int _8MB = 8 * 1024 * 1024;public static void main(String[] args) throws InterruptedException {new Thread(() -> {ArrayList<byte[]> list = new ArrayList<>();}).start();System.out.println("sleep....");Thread.sleep(1000L);}}/*其中def new generation,eden space是新生代,tenured generation是老年代,from,to幸存區Heap def new generationtotal 9216K, used 4510K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)eden space 8192K,55% used [0x00000000fec00000, 0x00000000ff067aa0, 0x00000000ff400000)from space 1024K,0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)tospace 1024K,0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000) tenured generationtotal 10240K, used 0K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)the space 10240K,0% used [0x00000000ff600000, 0x00000000ff600000, 0x00000000ff600200, 0x0000000100000000) Metaspaceused 4362K, capacity 4714K, committed 4992K, reserved 1056768Kclass spaceused 480K, capacity 533K, committed 640K, reserved 1048576K*//*然后我們展示添加1mb的情況*/package cn.itcast.jvm.t2;import java.util.ArrayList;public class Demo2_1 {private static final int _512KB = 512 * 1024;private static final int _1MB = 1024 * 1024;private static final int _6MB = 6 * 1024 * 1024;private static final int _7MB = 7 * 1024 * 1024;private static final int _8MB = 8 * 1024 * 1024;public static void main(String[] args) throws InterruptedException {new Thread(() -> {ArrayList<byte[]> list = new ArrayList<>();list.add(new byte[_1MB]);}).start();System.out.println("sleep....");Thread.sleep(1000L);}}/*我們可以發現新生代數據增加,老年代未發生變化Heap def new generationtotal 9216K, used 5534K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)eden space 8192K,67% used [0x00000000fec00000, 0x00000000ff167a40, 0x00000000ff400000)from space 1024K,0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)tospace 1024K,0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000) tenured generationtotal 10240K, used 0K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)the space 10240K,0% used [0x00000000ff600000, 0x00000000ff600000, 0x00000000ff600200, 0x0000000100000000) Metaspaceused 4354K, capacity 4714K, committed 4992K, reserved 1056768Kclass spaceused 480K, capacity 533K, committed 640K, reserved 1048576*//*最后需要補充講解一點:當我們的新生代不足以裝載數據內存時,我們會直接將其裝入老年代(老年代能夠裝載情況下)*/package cn.itcast.jvm.t2;import java.util.ArrayList;public class Demo2_1 {private static final int _512KB = 512 * 1024;private static final int _1MB = 1024 * 1024;private static final int _6MB = 6 * 1024 * 1024;private static final int _7MB = 7 * 1024 * 1024;private static final int _8MB = 8 * 1024 * 1024;public static void main(String[] args) throws InterruptedException {new Thread(() -> {ArrayList<byte[]> list = new ArrayList<>();list.add(new byte[_8MB]);}).start();System.out.println("sleep....");Thread.sleep(1000L);}}/*我們會發現eden的值未發生變化 , 但是tenured generation里面裝載了8192KHeap def new generationtotal 9216K, used 4510K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)eden space 8192K,55% used [0x00000000fec00000, 0x00000000ff067a30, 0x00000000ff400000)from space 1024K,0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)tospace 1024K,0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000) tenured generationtotal 10240K, used 8192K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)the space 10240K,80% used [0x00000000ff600000, 0x00000000ffe00010, 0x00000000ffe00200, 0x0000000100000000) Metaspaceused 4360K, capacity 4714K, committed 4992K, reserved 1056768Kclass spaceused 480K, capacity 533K, committed 640K, reserved 1048576K*//*當然,當我們的新生代和老年代都不足以裝載時 , 系統報錯~*/package cn.itcast.jvm.t2;import java.util.ArrayList;public class Demo2_1 {private static final int _512KB = 512 * 1024;private static final int _1MB = 1024 * 1024;private static final int _6MB = 6 * 1024 * 1024;private static final int _7MB = 7 * 1024 * 1024;private static final int _8MB = 8 * 1024 * 1024;public static void main(String[] args) throws InterruptedException {new Thread(() -> {ArrayList<byte[]> list = new ArrayList<>();list.add(new byte[_8MB]);list.add(new byte[_8MB]);}).start();System.out.println("sleep....");Thread.sleep(1000L);}}/*我們首先會看到他在Full gc之前做了一次小gc,然后做了一次Full gc,可是這并無法解決問題[GC (Allocation Failure) [DefNew: 4345K->999K(9216K), 0.0016573 secs][Tenured: 8192K->9189K(10240K), 0.0022899 secs] 12537K->9189K(19456K), [Metaspace: 4352K->4352K(1056768K)], 0.0039931 secs] [Times: user=0.00 sys=0.00, real=0.00 secs][Full GC (Allocation Failure) [Tenured: 9189K->9124K(10240K), 0.0018331 secs] 9189K->9124K(19456K), [Metaspace: 4352K->4352K(1056768K)], 0.0018528 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 然后系統進行報錯Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space at cn.itcast.jvm.t2.Demo2_1.lambda$main$0(Demo2_1.java:20) at cn.itcast.jvm.t2.Demo2_1$$Lambda$1/1023892928.run(Unknown Source) at java.lang.Thread.run(Thread.java:750)最后我們可以看到老年代占用了89%,第一個數據仍舊保存,但第二個數據無法保存導致報錯Heap def new generationtotal 9216K, used 366K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)eden space 8192K,4% used [0x00000000fec00000, 0x00000000fec5baa8, 0x00000000ff400000)from space 1024K,0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000)tospace 1024K,0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) tenured generationtotal 10240K, used 9124K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)the space 10240K,89% used [0x00000000ff600000, 0x00000000ffee93c0, 0x00000000ffee9400, 0x0000000100000000) Metaspaceused 4379K, capacity 4704K, committed 4992K, reserved 1056768Kclass spaceused 480K, capacity 528K, committed 640K, reserved 1048576K我們還需要注意的是:即使內存不足發生報錯,但該程序不會結束;系統只會釋放自己當前項目的進程而不會影響其他進程*/

推薦閱讀