import com.zb.gc.Test2;
import java.lang.ref.*;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class Reference1 {
public static void main(String[] args) {
title("强引用");
strangeReferenceTest();
title("软引用");
softReferenceTest();
title("弱引用");
weakReferenceTest();
title("虚引用");
phantomReferenceTest();
title("虚引用2");
phantomReferenceTest2();
}
private static void title(String title) {
System.out.println();
System.out.println();
System.out.println(title);
}
private static void printMemory(String message, Reference<byte[]> sr) {
System.out.println(message + ", 结果:sc=" + sr.get());
}
private static void printMemory(String message, Object obj) {
System.out.println(message + ", 结果:sc=" + obj);
}
/**
* ==========================================================
* ==========强引用、软引用、弱引用、虚引用
* ==========================================================
*/
//强引用
private static void strangeReferenceTest() {
//1.设定堆空间大小:VM.options='-Xmx20m'
//2.开辟内存空间10MB(软引用)
byte[] oldMemory = new byte[1024 * 1024 * 10];
printMemory("一阶段:开辟10MB", oldMemory);//查看内存地址
//3.gc主动回收
System.gc();
printMemory("二阶段:GC回收", oldMemory);//查看内存地址
//4.开辟新内存空间10MB(强引用)
byte[] newMemory = new byte[1024 * 1024 * 10];
printMemory("三阶段:再开辟10MB", oldMemory);//查看内存地址
}
//软引用:当[gc_full]时释放
private static void softReferenceTest() {
//1.设定堆空间大小:VM.options='-Xmx20m'
//2.开辟内存空间10MB(软引用)
SoftReference<byte[]> sr = new SoftReference<>(new byte[1024 * 1024 * 10]);
printMemory("一阶段:开辟10MB", sr);//查看内存地址
//3.gc主动回收
System.gc();
printMemory("二阶段:GC回收", sr);//查看内存地址
//4.开辟新内存空间10MB(强引用)
byte[] newMemory = new byte[1024 * 1024 * 10];
printMemory("三阶段:再开辟10MB", sr);//查看内存地址
}
//弱引用:当[手动gc]时释放
private static void weakReferenceTest() {
//1.设定堆空间大小:VM.options='-Xmx20m'
//2.开辟内存空间10MB(弱引用)
WeakReference<byte[]> wr = new WeakReference<>(new byte[1024 * 1024 * 10]);
printMemory("一阶段 开辟10MB", wr);//查看内存地址
//3.gc主动回收
System.gc();
printMemory("二阶段 GC回收", wr);//查看内存地址
//4.开辟新内存空间10MB(强引用)
byte[] newMemory = new byte[1024 * 1024 * 10];
printMemory("三阶段 再开辟10MB", wr);//查看内存地址
}
private static final ReferenceQueue<byte[]> QUEUE = new ReferenceQueue<>();
//虚引用:开辟在主内存而不是jvm内存,跟gc无关
private static void phantomReferenceTest() {
//1.设定堆空间大小:VM.options='-Xmx20m'
//2.开辟内存空间10MB(虚引用)
PhantomReference<byte[]> pr = new PhantomReference<>(new byte[1024 * 1024 * 10], QUEUE);
printMemory("一阶段 开辟10MB", pr);//查看内存地址
//3.gc主动回收
System.gc();
printMemory("二阶段 GC回收", pr);//查看内存地址
//4.开辟新内存空间10MB(强引用)
byte[] newMemory = new byte[1024 * 1024 * 10];
printMemory("三阶段 再开辟10MB", pr);//查看内存地址
}
private static final List<byte[]> LIST1 = new LinkedList<>();
private static final ReferenceQueue<Reference1> QUEUE1 = new ReferenceQueue<>();
private static void phantomReferenceTest2(){
//开辟内存空间10MB
PhantomReference<Reference1> pr = new PhantomReference<>(new Reference1(), QUEUE1);
printMemory("一阶段 开辟10MB", pr);
//循环在LIST1中开辟内存空间10MB
new Thread(()->{
while(true){
LIST1.add(new byte[1024 * 1024]);
printMemory("二阶段 循环开辟10MB", pr);
}
//内存不足之后,M对象会被回收,会放入到QUEUE中
}).start();
//
new Thread(()->{
while(true){
Reference<? extends Reference1> poll = QUEUE1.poll();
if(poll != null) {
System.out.println("三阶段 虚引用对象被JVM回收" + poll);
}
}
}).start();
}
}
08-15
1622