强软弱虚
强
普通的引用就是强引用——Object o=new Object,只要还有变量指向该对象,gc就一定不会回收。注:垃圾回收的优先级很低,system.gc()不一定能立刻触发垃圾回收
示例
public static void main(String[] args) {
Person person = new Person();
System.out.println(person);
person=null;
System.gc();
for(int i=0;i<10;i++){
System.out.println("阻塞垃圾回收");
}
}
输出结果
Person{name='null'}
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
调用垃圾回收器
软
软引用的使用方式——SoftRefernce
软引用所指向的对象reference ,只有堆内存不够时,gc才会回收reference。主要用于缓存
使用方法
public class TestCitation {
public static void main(String[] args) {
TestCitation testCitation = new TestCitation();
testCitation.softCitation();
}
/**
* 强引用
*/
public void strongCitation(){
//强引用
Person person = new Person();
System.out.println(person);
person=null;
System.gc();
for(int i=0;i<10;i++){
System.out.println("阻塞垃圾回收");
}
}
/**
* 软引用
*/
public void softCitation(){
SoftReference<byte[]> reference = new SoftReference<>(new byte[1024*1024*10]);
System.out.println(reference.get());
System.gc();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(reference.get());
byte[] bytes = new byte[1024 * 1024 * 15];
System.out.println(reference.get());
}
}
输出结果
[B@4554617c
[B@4554617c
null
弱
gc干活就会被回收。
只要强引用被回收,弱引用所对应的引用也会被回收,不需要做额外处理。一般用于容器中。ThreadLocal是用ThreadLocalMap实现,ThreadLocalMap存储的key-value的key值是ThreadLocal,ThreadLocalMap用的就是弱引用
ThreadLocalMap实现
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
使用方式
WeakReference<Person> weakReference = new WeakReference<>(new Person());
System.out.println(weakReference.get());
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(weakReference.get());
输出结果
Person{name='null'}
null
WeakHashMap
public void weakHashMapCitation(){
WeakHashMap<Person, String> weakHashMap = new WeakHashMap<>();
Person person = new Person();
person.setName("123");
weakHashMap.put(person,"xdfsdf");
System.out.println(weakHashMap);
person=null;
System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(weakHashMap);
}
输出结果
{Person{name='123'}=xdfsdf}
{}
虚
管理堆外内存,写jvm用,写程序不需要。一旦虚引用指向的person被回收,则把该对象放在queue队列中。只要gc工作,就一定会回收虚引用对象。虚引用无法获取里面的值,主要是为了通知。堆外内存无法由jvm回收
使用场景
管理堆外内存——DirectByteBuffer
大概写法
PhantomReference<Person> reference = new PhantomReference<Person>(new Person(), queue);
使用方式
定义虚内存并把内存塞满
PhantomReference<Person> reference = new PhantomReference<Person>(new Person(), queue);
LinkedList<Object> objectList = new LinkedList<>();
new Thread(()->{
while (true){
objectList.add(new byte[1024*1024*5]);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(reference.get());
}
}).start();
再开多个线程检测队列是否为空
new Thread(()->{
while (true){
Reference<? extends Person> poll = queue.poll();
if(poll!=null){
System.out.println("触发垃圾回收——————————"+poll);
}
}
}).start();
运行结果
null
null
触发垃圾回收——————————java.lang.ref.PhantomReference@2d46c162
null
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
at com.me.thread.TestCitation.lambda$phantomCitation$0(TestCitation.java:88)
at com.me.thread.TestCitation$$Lambda$1/821270929.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)