首页
统计
壁纸
关于我
Search
1
Mysql delete from table 和 truncate table 的区别
881 阅读
2
Spring AOP 术语说明
764 阅读
3
MySQL事务隔离级别
699 阅读
4
Java引用类型:强引用、软引用、弱引用、软引用
631 阅读
5
好冷
97 阅读
随笔
时政
技术
登录
Search
标签搜索
Java
Mysql
Xiaodong
累计撰写
6
篇文章
累计收到
28
条评论
首页
栏目
随笔
时政
技术
页面
统计
壁纸
关于我
搜索到
6
篇与
的结果
2020-06-28
Java引用类型:强引用、软引用、弱引用、软引用
jdk从1.2开始,把对象的引用分为四个类型,这四种引用类型从生命周期从长到短依次是:强引用、软引用、弱引用、虚引用。Java引入这四种引用类型的目标主要有两个:一个是可以让程序员通过代码的方式控制对象的生命周期;一个是有利于jvm进行垃圾回收。强引用程序中最普遍的默认对象引用,也是程序开发中最常用的引用类型。JVM的垃圾回收期在任何时候都不会回收强引用。即使当内存空间不足抛出内存溢出(OOM),也不会回收具有强引用的对象来释放内存。我们可以显式的赋值对象为null,来告诉gc该对象不存在引用,这时gc就可以回收这个对象,但具体什么时候收集还是要取决于gc的算法。比如ArraryList类的clear方法中就是通过将引用赋值为null来实现清理工作/** * Removes all of the elements from this list. The list will * be empty after this call returns. */ public void clear() { modCount++; // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; }软引用软引用用来描述一些有用但不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。比如下面的代码,即使obj赋值为null,软引用关联对象在内存充足的情况不会被回收。public class TestSoftReference { public static void main(String[] args) { Obj obj = new Obj("SoftReference"); SoftReference<Obj> sr = new SoftReference<>(obj); obj = null; System.gc(); System.out.println(sr.get().getName()); } } @Data @AllArgsConstructor class Obj { private String name; }运行结果:SoftReference弱引用弱引用用来描述一些非必须的对象。弱引用相比于软引用拥有更短的生命周期,当JVM运行垃圾回收的时候,不论内存是否充足,都会回收只被弱引用对象关联的对象。在java中,用java.lang.ref.WeakReference类来表示。比如下面的代码,obj赋值为null后,弱引用关联的对象会在执行垃圾回收后被回收。public class TestWeakReference { public static void main(String[] args) { Obj obj = new Obj("WeakReference"); WeakReference<Obj> wr = new WeakReference<>(obj); System.out.println(wr.get().getName()); System.out.println("----------------"); obj = null; System.out.println(wr.get().getName()); System.out.println("----------------"); // 推荐gc来回收 System.gc(); System.out.println(wr.get().getName()); } }运行结果:WeakReference ---------------- WeakReference ---------------- Exception in thread "main" java.lang.NullPointerException at com.xiao.temporary.TestRefrence.main(TestRefrence.java:25)虚引用顾名思义,就是形同虚设,即对对象而言是无感知的。与其他几种引用类型不同,虚引用不会影响和决定对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动(即对象是否存活的监控)。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。比如下面的代码,通过是否入列ReferenceQueue可以判断对象是否被回收。public class TestPhantomReference { public static void main(String[] args) { Obj obj = new Obj("PhantomReference"); ReferenceQueue<Obj> referenceQueue = new ReferenceQueue<>(); PhantomReference<Obj> pr = new PhantomReference<>(obj, referenceQueue); // 永远为null System.out.println("pr.get:" + pr.get()); // 是否入队,和是否被回收有关 System.out.println("pr.isEnqueued:" + pr.isEnqueued()); // poll一下referenceQueue中的对象看看 System.out.println("referenceQueue.poll:" + referenceQueue.poll()); System.out.println("----------------"); obj = null; System.out.println("pr.get:" + pr.get()); System.out.println("pr.isEnqueued:" + pr.isEnqueued()); System.out.println("referenceQueue.poll:" + referenceQueue.poll()); System.out.println("----------------"); // 推荐gc来回收 System.gc(); System.out.println("pr.get:" + pr.get()); System.out.println("pr.isEnqueued:" + pr.isEnqueued()); System.out.println("referenceQueue.poll:" + referenceQueue.poll()); } }运行结果:pr.get:null pr.isEnqueued:false referenceQueue.poll:null ---------------- pr.get:null pr.isEnqueued:false referenceQueue.poll:null ---------------- pr.get:null pr.isEnqueued:true referenceQueue.poll:java.lang.ref.PhantomReference@610455d6总结引用类型被垃圾回收时间用途生存时间强引用从来不会对象的一般状态JVM停止运行时软引用内存不足时对象缓存内存不足时弱引用jvm垃圾回收时对象缓存gc运行后虚引用未知未知未知
2020年06月28日
631 阅读
6 评论
4 点赞
1
2