这是我参与更文挑战的第7天,活动详情查看: 更文挑战
来到更文的第七天,也是6.7高考的日子,正在参加高考的学弟学妹们,希望你们考啥啥会,金榜题名!
读这篇文章之前可以先看一下上面这个链接的第四小节,可以帮助我们理解这四种引用!
这篇文章介绍一下Java的四种引用,给介绍ThreadLocal做准备! Java内存管理分为内存分配,和内存回收,内存回收是由垃圾回收器自己负责的,有专门的垃圾回收机制,而垃圾回收机制主要看对象是否有引用指向这个对象,而引用的强弱,就是这四种引用:强引用,软引用,弱引用,和虚引用!
1、强引用
强引用是指创建一个对象并赋给它一个引用,这个就是强引用
praivate static void strongReference(String[] args){
Object o=new Object();
//TO Do 做很多事情
//TO DO 做很多事情
}
因为o 是局部变量在strongReference方法执行完的时候,o会被JVM自动回收,但是因为它是一个强引用,当strongReference还没执行完的时候内存不够用了,JVM是不会回收 o的,会抛出out of Memory异常!,如果想中断引用,直接把o置为null即可,然后gc回收的时候就会o的实例回收掉
2、软引用
如果一个对象具有软引用,只要内存足够,它就不会被GC回收,只有即将快要发生oom的时候,gc会回收具有软引用的对象 GC:快要发生OOM了!
具有软引用的对象:
GC:走你!
GC就把具有软引用的对象给带走了! 软引用可以用于内存敏感的缓存,比如图片缓存,内存不足的时候图片加载不出来,但是不会oom,这样我们的代码就会好很多
public class TestDemo {
static class User{
}
public static void main(String[] args) {
User user=new User();//这是一个强引用
SoftReference<User> userSoftReference=new SoftReference<>(user);//软引用
user=null;
System.out.println(userSoftReference.get());//确定这个对象是否还在
System.gc();//进行一次垃圾回收,这个代码千万不要写到业务代码中
System.out.println(userSoftReference.get());
List<byte[]> list=new LinkedList<>();
try {
for (;;){
list.add(new byte[1024*100]);
}
}catch (Throwable throwable){
throwable.printStackTrace();
//这个时候持有软引用的User已经走你了
System.out.println(userSoftReference.get());
}
}
}
运行结果
3、弱引用
弱引用比软引用还要弱一点,只存活在下一次gc之前,用于不是那么重要的数据的引用
public static void main(String[] args) {
User user=new User();//这是一个强引用
WeakReference<User> userWeakReference=new WeakReference<>(user);//弱引用
user=null;
System.out.println(userWeakReference.get());//确定这个对象是否还在
System.gc();//进行一次垃圾回收,这个代码千万不要写到业务代码中
System.out.println(userWeakReference.get());
}
运行结果:
弱引用的使用场景和软引用差不多,只是弱引用它的生命周期更短一些, 弱引用的使用场景,Handler内存泄漏,ThreadLocal里的ThreadLocalMap的Entry
使用它们就是为了避免内存泄漏
4、虚引用PhantomReference
虚引用也叫幽灵引用,随时可能被回收掉,它在使用的时候必须集合ReferenceQueue
public static void main(String[] args) throws FileNotFoundException {
ReferenceQueue<String> referenceQueue=new ReferenceQueue<>();
PhantomReference<String> phantomReference=new PhantomReference<>(new String("aa"),referenceQueue);
System.out.println(phantomReference.get());
}
运行结果:
这个虚引用在我们平时开发中,很少用到。它的作用就是来监听垃圾回收器是否在正常工作!
5、总结
四个引用,其实代表了垃圾回收时的优先级,强引用如果不中断引用的话不会被回收的,即使你发生了oom,而软引用就是内存不够的时候,垃圾回收器才会回收它,而弱引用只要发生垃圾回收,它就会被回收,虚引用只要出来它就会被回收,说明gc是在正常工作,如果没有被回收,可能垃圾回收器出现了问题!