文章目录
环境
/**
* -Xmx64M 最大堆大小
* -Xms64M 初始化堆大小
* -XX:+PrintGCDetails 在控制台输出GC详细信息
* -Xmx64M -Xms64M -XX:+PrintGCDetails
*/
jdk\jdk11.0.9_11\bin\java.exe -Xmx64M -Xms64M -XX:+PrintGCDetails
StrongReference
是我们平时使用最多的一种对象引用,当一个对象被关键字new实例化出来的时候,JVM会在堆内存开辟一片内存区域,用于存放与该实例对应的数据结构。
JVM垃圾回收器线程会在达到GC条件时尝试回收堆栈内存中的数据,强引用的的点是只要应用到ROOT根的路径可达,无论怎样的GC都不会将其释放,而是宁可出现JVM内存溢出。
如Object object =new Object();
String str =“hello world”;
private void testStrongReference() {
List<Reference> list = new ArrayList<>();
for (int i=0; i< 10; i++) {
Reference reference = new Reference();
list.add(reference);
}
System.out.println(list.size());
/**
* jdk\jdk11.0.9_11\bin\java.exe -Xmx64M -Xms64M -XX:+PrintGCDetails
* [0.004s][warning][gc] -XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead.
* [0.015s][info ][gc,heap] Heap region size: 1M
* [0.018s][info ][gc ] Using G1
* [0.018s][info ][gc,heap,coops] Heap address: 0x00000000fc000000, size: 64 MB, Compressed Oops mode: 32-bit
* [0.147s][info ][gc,start ] GC(0) Pause Young (Concurrent Start) (G1 Humongous Allocation)
* [0.147s][info ][gc,task ] GC(0) Using 2 workers of 10 for evacuation
* [0.149s][info ][gc,phases ] GC(0) Pre Evacuate Collection Set: 0.0ms
* [0.149s][info ][gc,phases ] GC(0) Evacuate Collection Set: 1.5ms
* [0.149s][info ][gc,phases ] GC(0) Post Evacuate Collection Set: 0.1ms
* [0.149s][info ][gc,phases ] GC(0) Other: 0.3ms
* [0.149s][info ][gc,heap ] GC(0) Eden regions: 4->0(29)
* [0.149s][info ][gc,heap ] GC(0) Survivor regions: 0->1(3)
* [0.149s][info ][gc,heap ] GC(0) Old regions: 0->0
* [0.149s][info ][gc,heap ] GC(0) Humongous regions: 22->22
* [0.149s][info ][gc,metaspace ] GC(0) Metaspace: 6403K->6403K(1056768K)
* [0.149s][info ][gc ] GC(0) Pause Young (Concurrent Start) (G1 Humongous Allocation) 25M->22M(64M) 2.060ms
* [0.149s][info ][gc,cpu ] GC(0) User=0.00s Sys=0.00s Real=0.00s
* [0.149s][info ][gc ] GC(1) Concurrent Cycle
* [0.149s][info ][gc,marking ] GC(1) Concurrent Clear Claimed Marks
* [0.149s][info ][gc,marking ] GC(1) Concurrent Clear Claimed Marks 0.005ms
* [0.149s][info ][gc,marking ] GC(1) Concurrent Scan Root Regions
* [0.150s][info ][gc,marking ] GC(1) Concurrent Scan Root Regions 0.464ms
* [0.150s][info ][gc,marking ] GC(1) Concurrent Mark (0.150s)
* [0.150s][info ][gc,marking ] GC(1) Concurrent Mark From Roots
* [0.150s][info ][gc,task ] GC(1) Using 3 workers of 3 for marking
* [0.150s][info ][gc,marking ] GC(1) Concurrent Mark From Roots 0.301ms
* [0.150s][info ][gc,marking ] GC(1) Concurrent Preclean
* [0.150s][info ][gc,marking ] GC(1) Concurrent Preclean 0.123ms
* [0.150s][info ][gc,marking ] GC(1) Concurrent Mark (0.150s, 0.150s) 0.453ms
* [0.153s][info ][gc,start ] GC(1) Pause Remark
* [0.154s][info ][gc,stringtable] GC(1) Cleaned string and symbol table, strings: 2912 processed, 0 removed, symbols: 26607 processed, 0 removed
* [0.154s][info ][gc ] GC(1) Pause Remark 33M->33M(64M) 0.582ms
* [0.154s][info ][gc,cpu ] GC(1) User=0.00s Sys=0.00s Real=0.00s
* [0.154s][info ][gc,marking ] GC(1) Concurrent Rebuild Remembered Sets
* [0.154s][info ][gc,marking ] GC(1) Concurrent Rebuild Remembered Sets 0.073ms
* [0.158s][info ][gc,start ] GC(1) Pause Cleanup
* [0.158s][info ][gc ] GC(1) Pause Cleanup 45M->45M(64M) 0.081ms
* [0.158s][info ][gc,cpu ] GC(1) User=0.00s Sys=0.00s Real=0.00s
* [0.158s][info ][gc,marking ] GC(1) Concurrent Cleanup for Next Mark
* [0.158s][info ][gc,marking ] GC(1) Concurrent Cleanup for Next Mark 0.075ms
* [0.158s][info ][gc ] GC(1) Concurrent Cycle 8.769ms
* [0.162s][info ][gc,start ] GC(2) Pause Young (Concurrent Start) (G1 Humongous Allocation)
* [0.162s][info ][gc,task ] GC(2) Using 2 workers of 10 for evacuation
* [0.163s][info ][gc,phases ] GC(2) Pre Evacuate Collection Set: 0.0ms
* [0.163s][info ][gc,phases ] GC(2) Evacuate Collection Set: 1.1ms
* [0.163s][info ][gc,phases ] GC(2) Post Evacuate Collection Set: 0.1ms
* [0.163s][info ][gc,phases ] GC(2) Other: 0.1ms
* [0.163s][info ][gc,heap ] GC(2) Eden regions: 1->0(2)
* [0.163s][info ][gc,heap ] GC(2) Survivor regions: 1->1(4)
* [0.163s][info ][gc,heap ] GC(2) Old regions: 0->0
* [0.163s][info ][gc,heap ] GC(2) Humongous regions: 55->55
* [0.163s][info ][gc,metaspace ] GC(2) Metaspace: 6403K->6403K(1056768K)
* [0.163s][info ][gc ] GC(2) Pause Young (Concurrent Start) (G1 Humongous Allocation) 56M->56M(64M) 1.339ms
* [0.163s][info ][gc,cpu ] GC(2) User=0.00s Sys=0.00s Real=0.00s
* [0.164s][info ][gc ] GC(3) Concurrent Cycle
* [0.164s][info ][gc,marking ] GC(3) Concurrent Clear Claimed Marks
* [0.164s][info ][gc,marking ] GC(3) Concurrent Clear Claimed Marks 0.005ms
* [0.164s][info ][gc,marking ] GC(3) Concurrent Scan Root Regions
* [0.164s][info ][gc,marking ] GC(3) Concurrent Scan Root Regions 0.509ms
* [0.164s][info ][gc,marking ] GC(3) Concurrent Mark (0.164s)
* [0.164s][info ][gc,marking ] GC(3) Concurrent Mark From Roots
* [0.164s][info ][gc,start ] GC(4) Pause Young (Normal) (G1 Humongous Allocation)
* [0.164s][info ][gc,task ] GC(3) Using 3 workers of 3 for marking
* [0.164s][info ][gc,task ] GC(4) Using 2 workers of 10 for evacuation
* [0.165s][info ][gc,phases ] GC(4) Pre Evacuate Collection Set: 0.4ms
* [0.165s][info ][gc,phases ] GC(4) Evacuate Collection Set: 1.1ms
* [0.165s][info ][gc,phases ] GC(4) Post Evacuate Collection Set: 0.1ms
* [0.165s][info ][gc,phases ] GC(4) Other: 0.0ms
* [0.165s][info ][gc,heap ] GC(4) Eden regions: 0->0(2)
* [0.165s][info ][gc,heap ] GC(4) Survivor regions: 1->1(1)
* [0.165s][info ][gc,heap ] GC(4) Old regions: 0->1
* [0.165s][info ][gc,heap ] GC(4) Humongous regions: 55->55
* [0.165s][info ][gc,metaspace ] GC(4) Metaspace: 6403K->6403K(1056768K)
* [0.165s][info ][gc ] GC(4) Pause Young (Normal) (G1 Humongous Allocation) 56M->56M(64M) 1.248ms
* [0.165s][info ][gc,cpu ] GC(4) User=0.00s Sys=0.00s Real=0.00s
* [0.165s][info ][gc,task ] GC(5) Using 2 workers of 10 for full compaction
* [0.165s][info ][gc,start ] GC(5) Pause Full (G1 Humongous Allocation)
* [0.165s][info ][gc,phases,start] GC(5) Phase 1: Mark live objects
* [0.166s][info ][gc,stringtable ] GC(5) Cleaned string and symbol table, strings: 2912 processed, 3 removed, symbols: 26607 processed, 0 removed
* [0.166s][info ][gc,phases ] GC(5) Phase 1: Mark live objects 0.998ms
* [0.166s][info ][gc,phases,start] GC(5) Phase 2: Prepare for compaction
* [0.167s][info ][gc,phases ] GC(5) Phase 2: Prepare for compaction 0.270ms
* [0.167s][info ][gc,phases,start] GC(5) Phase 3: Adjust pointers
* [0.167s][info ][gc,phases ] GC(5) Phase 3: Adjust pointers 0.571ms
* [0.167s][info ][gc,phases,start] GC(5) Phase 4: Compact heap
* [0.168s][info ][gc,phases ] GC(5) Phase 4: Compact heap 0.270ms
* [0.168s][info ][gc,heap ] GC(5) Eden regions: 0->0(3)
* [0.168s][info ][gc,heap ] GC(5) Survivor regions: 1->0(1)
* [0.168s][info ][gc,heap ] GC(5) Old regions: 1->2
* [0.168s][info ][gc,heap ] GC(5) Humongous regions: 55->55
* [0.168s][info ][gc,metaspace ] GC(5) Metaspace: 6403K->6403K(1056768K)
* [0.168s][info ][gc ] GC(5) Pause Full (G1 Humongous Allocation) 56M->55M(64M) 2.429ms
* [0.168s][info ][gc,cpu ] GC(5) User=0.00s Sys=0.00s Real=0.00s
* [0.168s][info ][gc,task ] GC(6) Using 2 workers of 10 for full compaction
* [0.168s][info ][gc,start ] GC(6) Pause Full (G1 Humongous Allocation)
* [0.168s][info ][gc,phases,start] GC(6) Phase 1: Mark live objects
* [0.169s][info ][gc,stringtable ] GC(6) Cleaned string and symbol table, strings: 2909 processed, 2 removed, symbols: 26607 processed, 0 removed
* [0.169s][info ][gc,phases ] GC(6) Phase 1: Mark live objects 0.959ms
* [0.169s][info ][gc,phases,start] GC(6) Phase 2: Prepare for compaction
* [0.169s][info ][gc,phases ] GC(6) Phase 2: Prepare for compaction 0.341ms
* [0.169s][info ][gc,phases,start] GC(6) Phase 3: Adjust pointers
* [0.170s][info ][gc,phases ] GC(6) Phase 3: Adjust pointers 0.548ms
* [0.170s][info ][gc,phases,start] GC(6) Phase 4: Compact heap
* [0.170s][info ][gc,phases ] GC(6) Phase 4: Compact heap 0.247ms
* [0.170s][info ][gc,heap ] GC(6) Eden regions: 0->0(3)
* [0.170s][info ][gc,heap ] GC(6) Survivor regions: 0->0(1)
* [0.170s][info ][gc,heap ] GC(6) Old regions: 2->2
* [0.170s][info ][gc,heap ] GC(6) Humongous regions: 55->55
* [0.170s][info ][gc,metaspace ] GC(6) Metaspace: 6403K->6403K(1056768K)
* [0.170s][info ][gc ] GC(6) Pause Full (G1 Humongous Allocation) 55M->55M(64M) 2.340ms
* [0.170s][info ][gc,cpu ] GC(6) User=0.00s Sys=0.00s Real=0.00s
* [0.170s][info ][gc,marking ] GC(3) Concurrent Mark From Roots 6.423ms
* [0.170s][info ][gc,marking ] GC(3) Concurrent Mark Abort
* [0.170s][info ][gc ] GC(3) Concurrent Cycle 6.989ms
* Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
* at com.james.example.thread.jcp_multithread_architecture.chapter25.ReferenceTest$Reference.<init>(ReferenceTest.java:174)
* at com.james.example.thread.jcp_multithread_architecture.chapter25.ReferenceTest.main(ReferenceTest.java:27)
* [0.172s][info ][gc,heap,exit ] Heap
* [0.172s][info ][gc,heap,exit ] garbage-first heap total 65536K, used 57292K [0x00000000fc000000, 0x0000000100000000)
* [0.172s][info ][gc,heap,exit ] region size 1024K, 1 young (1024K), 0 survivors (0K)
* [0.172s][info ][gc,heap,exit ] Metaspace used 6419K, capacity 6479K, committed 6528K, reserved 1056768K
* [0.172s][info ][gc,heap,exit ] class space used 566K, capacity 602K, committed 640K, reserved 1048576K
*/
}
}
SoftReference
如果一个对象具有软引用,内存空间足够,垃圾回收器就不会回收它;
如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存,比如网页缓存、图片缓存等。使用软引用能防止内存泄露,增强程序的健壮性。
特点是它的一个实例保存对一个Java对象的软引用, 该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。也就是说,一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对 这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。
注意: 一旦垃圾线程回收该Java对象之 后,get()方法将返回null。
private static void testSoftReference() {
/**
* 只有当内存不够时,执行GC时才会回收
*/
Reference ref = new Reference();
SoftReference<Reference> softReference = new SoftReference<>(ref);
ref = null;
System.gc();
/**
* jdk\jdk11.0.9_11\bin\java.exe -Xmx64M -Xms64M -XX:+PrintGCDetails
* [0.004s][warning][gc] -XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead.
* [0.014s][info ][gc,heap] Heap region size: 1M
* [0.016s][info ][gc ] Using G1
* [0.016s][info ][gc,heap,coops] Heap address: 0x00000000fc000000, size: 64 MB, Compressed Oops mode: 32-bit
* [0.132s][info ][gc,task ] GC(0) Using 2 workers of 10 for full compaction
* [0.132s][info ][gc,start ] GC(0) Pause Full (System.gc())
* [0.132s][info ][gc,phases,start] GC(0) Phase 1: Mark live objects
* [0.133s][info ][gc,stringtable ] GC(0) Cleaned string and symbol table, strings: 2911 processed, 3 removed, symbols: 26557 processed, 0 removed
* [0.133s][info ][gc,phases ] GC(0) Phase 1: Mark live objects 1.543ms
* [0.133s][info ][gc,phases,start] GC(0) Phase 2: Prepare for compaction
* [0.134s][info ][gc,phases ] GC(0) Phase 2: Prepare for compaction 0.275ms
* [0.134s][info ][gc,phases,start] GC(0) Phase 3: Adjust pointers
* [0.134s][info ][gc,phases ] GC(0) Phase 3: Adjust pointers 0.512ms
* [0.134s][info ][gc,phases,start] GC(0) Phase 4: Compact heap
* [0.135s][info ][gc,phases ] GC(0) Phase 4: Compact heap 0.534ms
* [0.135s][info ][gc,heap ] GC(0) Eden regions: 4->0(23)
* [0.135s][info ][gc,heap ] GC(0) Survivor regions: 0->0(0)
* [0.135s][info ][gc,heap ] GC(0) Old regions: 0->2
* [0.135s][info ][gc,heap ] GC(0) Humongous regions: 11->11
* [0.135s][info ][gc,metaspace ] GC(0) Metaspace: 6357K->6357K(1056768K)
* [0.135s][info ][gc ] GC(0) Pause Full (System.gc()) 14M->11M(64M) 3.199ms
* [0.135s][info ][gc,cpu ] GC(0) User=0.02s Sys=0.00s Real=0.00s
* [0.136s][info ][gc,heap,exit ] Heap
* [0.136s][info ][gc,heap,exit ] garbage-first heap total 65536K, used 12225K [0x00000000fc000000, 0x0000000100000000)
* [0.136s][info ][gc,heap,exit ] region size 1024K, 1 young (1024K), 0 survivors (0K)
* [0.136s][info ][gc,heap,exit ] Metaspace used 6405K, capacity 6479K, committed 6528K, reserved 1056768K
* [0.136s][info ][gc,heap,exit ] class space used 564K, capacity 602K, committed 640K, reserved 1048576K
*/
}
WeakReferenc
弱引用也是用来描述非必需对象的,当JVM进行任何类型的垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象
/**
* 无论YoungGc 还是Full GC 无论内存空间是否有空闲,只要执行GC 即被回收
*/
private static void testWeakReference() {
Reference ref = new Reference();
WeakReference<Reference> weakReference = new WeakReference<>(ref);
ref = null;
System.gc();
/**
* jdk\jdk11.0.9_11\bin\java.exe -Xmx64M -Xms64M -XX:+PrintGCDetails
* [0.005s][warning][gc] -XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead.
* [0.015s][info ][gc,heap] Heap region size: 1M
* [0.017s][info ][gc ] Using G1
* [0.017s][info ][gc,heap,coops] Heap address: 0x00000000fc000000, size: 64 MB, Compressed Oops mode: 32-bit
* [0.137s][info ][gc,task ] GC(0) Using 2 workers of 10 for full compaction
* [0.137s][info ][gc,start ] GC(0) Pause Full (System.gc())
* [0.137s][info ][gc,phases,start] GC(0) Phase 1: Mark live objects
* [0.138s][info ][gc,stringtable ] GC(0) Cleaned string and symbol table, strings: 2911 processed, 3 removed, symbols: 26557 processed, 0 removed
* [0.138s][info ][gc,phases ] GC(0) Phase 1: Mark live objects 1.597ms
* [0.138s][info ][gc,phases,start] GC(0) Phase 2: Prepare for compaction
* [0.139s][info ][gc,phases ] GC(0) Phase 2: Prepare for compaction 0.390ms
* [0.139s][info ][gc,phases,start] GC(0) Phase 3: Adjust pointers
* [0.139s][info ][gc,phases ] GC(0) Phase 3: Adjust pointers 0.647ms
* [0.139s][info ][gc,phases,start] GC(0) Phase 4: Compact heap
* [0.140s][info ][gc,phases ] GC(0) Phase 4: Compact heap 0.561ms
* [0.140s][info ][gc,heap ] GC(0) Eden regions: 4->0(23)
* [0.140s][info ][gc,heap ] GC(0) Survivor regions: 0->0(0)
* [0.140s][info ][gc,heap ] GC(0) Old regions: 0->2
* [0.140s][info ][gc,heap ] GC(0) Humongous regions: 11->11
* [0.140s][info ][gc,metaspace ] GC(0) Metaspace: 6356K->6356K(1056768K)
* [0.140s][info ][gc ] GC(0) Pause Full (System.gc()) 14M->11M(64M) 3.602ms
* [0.140s][info ][gc,cpu ] GC(0) User=0.00s Sys=0.00s Real=0.00s
* the reference will be GC
* [0.141s][info ][gc,heap,exit ] Heap
* [0.141s][info ][gc,heap,exit ] garbage-first heap total 65536K, used 13249K [0x00000000fc000000, 0x0000000100000000)
* [0.141s][info ][gc,heap,exit ] region size 1024K, 2 young (2048K), 0 survivors (0K)
* [0.141s][info ][gc,heap,exit ] Metaspace used 6407K, capacity 6479K, committed 6528K, reserved 1056768K
* [0.141s][info ][gc,heap,exit ] class space used 564K, capacity 602K, committed 640K, reserved 1048576K
*/
}
PhantomReference
虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。需要注意的是:虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。
与SoftReference和WeakReference相比较 Phantom Reference不同之处:
- Phantom Reference 必须与ReferenceQueue配合使用
- Phantom Reference 的get方法返回的始终是null
- 当垃圾回收器决定回收Phantom Reference对象的时候会将其插入关联的ReferenceQueue中
- 使用Phantom Reference 进行清理动作要比Object的finalize方法更灵活。
private static void testPhantomReference() {
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
System.out.println(pr.get());
/**
* jdk\jdk11.0.9_11\bin\java.exe -Xmx64M -Xms64M -XX:+PrintGCDetails
* [0.004s][warning][gc] -XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead.
* [0.015s][info ][gc,heap] Heap region size: 1M
* [0.018s][info ][gc ] Using G1
* [0.018s][info ][gc,heap,coops] Heap address: 0x00000000fc000000, size: 64 MB, Compressed Oops mode: 32-bit
* null
* [0.143s][info ][gc,heap,exit ] Heap
* [0.143s][info ][gc,heap,exit ] garbage-first heap total 65536K, used 3072K [0x00000000fc000000, 0x0000000100000000)
* [0.143s][info ][gc,heap,exit ] region size 1024K, 4 young (4096K), 0 survivors (0K)
* [0.143s][info ][gc,heap,exit ] Metaspace used 6171K, capacity 6255K, committed 6528K, reserved 1056768K
* [0.143s][info ][gc,heap,exit ] class space used 535K, capacity 570K, committed 640K, reserved 1048576K
*/
}
PhantomReference应用-SocketCleaningTracker
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.net.Socket;
/***
* SocketCleaningTracker 启动Cleaner线程(其被设置为守护线程,清理动作一般是系统的清理工作,
* 用于防止JVM无法正常关闭,如同JVM的GC线程的作用一样)
* 不断从ReferenceQueue中remove Tracker 实例(Tracker是一个PhantomReference的子类)
* 然后尝试进行最后的清理工作
*/
public class SocketCleaningTracker {
private static final ReferenceQueue<Object> queue = new ReferenceQueue<>();
static {
new Cleaner().start();
}
private static void track(Socket socket) {
new Tracker(socket, queue);
}
private static class Cleaner extends Thread {
private Cleaner() {
setDaemon(true);
}
@Override
public void run() {
for (; ; ) {
try {
// 当Tracker被垃圾回收器回收时会加入queue中
Tracker tracker = (Tracker) queue.remove();
tracker.close();
} catch (InterruptedException e) {
}
}
}
}
private static class Tracker extends PhantomReference<Object> {
private final Socket socket;
Tracker(Socket socket, ReferenceQueue<? super Object> q) {
super(socket, q);
this.socket = socket;
}
public void close() {
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
ReferenceQueue
使用ReferenceQueue清除失去了引用对象的SoftReference或者WeakReference,
从ReferenceQueue这个名字也可以看出,它是一个队列,当我们调用它的poll()方法的时候,如果这个队列中不是空队列,那么将返回队列前面的那个Reference对象。
在任何时候,我们都可以调用ReferenceQueue的poll()方法来检查是否有它所关心的非强可及对象被回收。如果队列为空,将返回一个null,否则该方法返回队列中前面的一个非強Reference对象。利用这个方法,我们可以检查哪个非強Reference所引用的对象已经被回收。于是我们可以把这些失去所引用的对象的非強Reference对象清除掉
private static void testReferenceQueue() throws InterruptedException {
/**
* 被垃圾回收的Reference会被加入与之关联的Queue中
*/
ReferenceQueue<Reference> queue = new ReferenceQueue<>();
Reference ref = new Reference();
WeakReference<Reference> weakReference = new WeakReference<>(ref, queue);
ref = null;
System.out.println("before gc: " + weakReference.get());
System.gc();
// make sure GC thread triggered.
TimeUnit.SECONDS.sleep(1);
System.out.println("after gc: " + weakReference.get());
java.lang.ref.Reference<? extends Reference> gcRef = queue.remove();
/**
* 被垃圾回收后,可以从队列中获得
*/
System.out.println("gcRef: " + gcRef);
System.out.println("gcRef get(): " + gcRef.get());
/**
* jdk11.0.9_11\bin\java.exe -Xmx64M -Xms64M -XX:+PrintGCDetails
* [0.004s][warning][gc] -XX:+PrintGCDetails is deprecated. Will use -Xlog:gc* instead.
* [0.014s][info ][gc,heap] Heap region size: 1M
* [0.016s][info ][gc ] Using G1
* [0.016s][info ][gc,heap,coops] Heap address: 0x00000000fc000000, size: 64 MB, Compressed Oops mode: 32-bit
* before gc: com.james.example.thread.jcp_multithread_architecture.chapter25.ReferenceTest$Reference@1cd072a9
* [0.136s][info ][gc,task ] GC(0) Using 2 workers of 10 for full compaction
* [0.136s][info ][gc,start ] GC(0) Pause Full (System.gc())
* [0.136s][info ][gc,phases,start] GC(0) Phase 1: Mark live objects
* [0.138s][info ][gc,stringtable ] GC(0) Cleaned string and symbol table, strings: 2913 processed, 3 removed, symbols: 26556 processed, 0 removed
* [0.138s][info ][gc,phases ] GC(0) Phase 1: Mark live objects 1.531ms
* [0.138s][info ][gc,phases,start] GC(0) Phase 2: Prepare for compaction
* [0.138s][info ][gc,phases ] GC(0) Phase 2: Prepare for compaction 0.292ms
* [0.138s][info ][gc,phases,start] GC(0) Phase 3: Adjust pointers
* [0.138s][info ][gc,phases ] GC(0) Phase 3: Adjust pointers 0.508ms
* [0.138s][info ][gc,phases,start] GC(0) Phase 4: Compact heap
* [0.139s][info ][gc,phases ] GC(0) Phase 4: Compact heap 0.545ms
* [0.139s][info ][gc,heap ] GC(0) Eden regions: 4->0(23)
* [0.139s][info ][gc,heap ] GC(0) Survivor regions: 0->0(0)
* [0.139s][info ][gc,heap ] GC(0) Old regions: 0->2
* [0.139s][info ][gc,heap ] GC(0) Humongous regions: 11->11
* [0.139s][info ][gc,metaspace ] GC(0) Metaspace: 6359K->6359K(1056768K)
* [0.139s][info ][gc ] GC(0) Pause Full (System.gc()) 14M->11M(64M) 3.194ms
* [0.139s][info ][gc,cpu ] GC(0) User=0.00s Sys=0.00s Real=0.00s
* the reference will be GC
* after gc: null
* gcRef: java.lang.ref.WeakReference@7c75222b
* gcRef get(): null
* [1.140s][info ][gc,heap,exit ] Heap
* [1.140s][info ][gc,heap,exit ] garbage-first heap total 65536K, used 14274K [0x00000000fc000000, 0x0000000100000000)
* [1.140s][info ][gc,heap,exit ] region size 1024K, 3 young (3072K), 0 survivors (0K)
* [1.140s][info ][gc,heap,exit ] Metaspace used 7330K, capacity 7397K, committed 7680K, reserved 1056768K
* [1.140s][info ][gc,heap,exit ] class space used 652K, capacity 672K, committed 768K, reserved 1048576K
*/}
Reference
public class Reference {
//10M
private final byte[] data = new byte[1024 * 1024 * 10];
protected void finalize() throws Exception {
System.out.println("the reference will be GC");
}
}