您的位置 首页 java

Java中的强软弱虚,你了解么?

为了充分利用计算机的内存,对象被设计成拥有生命周期。当对象的生命周期结束,会被垃圾回收器回收,从而释放内存资源。为了考虑回收的各种场景,在JDK1.2引用了强、软、弱、虚4种引用类型。

强引用

如果一个对象是强引用,那么垃圾回收器不会轻易回收它。只用当这个对象没有被使用,垃圾回收器才会回收它。

创建一个new StrongReference(),用一个引用strongReference去指向这块内存空间的地址,当引用置为null,垃圾回收器回收时,会出发finalize()方法。我们来看运行结果。

 StrongReference类被回收了!!!
  

如果这个对象一直被引用着,就算内存满了,也不会垃圾回收。宁愿抛出OutOfMemoryError。

但是,如果你不精通内存的回收,千万不要使用finalize()方法。

finalize()的作用往往被认为是用来做最后的资源回收。此方法有很大的不确定性(不保证方法中的任务执行完)而且运行代价较高。所以用来回收资源也不会有什么好的表现。

这里还有一个梗,当年小米工程师,很多是从C++转 Java 的。C++一般会需要手动清理内存,所以习惯重写finalize()方法。但是系统老是出现各种内存问题。最还是把垃圾清除的方法交给 JVM

软引用

当系统内存不足时,会触发GC。当垃圾回收后,内存还是不足,就会把软引用的包裹的对象给清理掉。

我们来测试test1()。测试结果:

  Student (grade=null)
  

这里对象并没有被回收,所以能拿到Student。

我们再来测试下test2(),为了模拟真实环境,这里将内存调整为20MB。

运行结果

 [B@7960847b
[B@7960847b
null
  

当创建了两个字节数组后,内存满了,触发GC,Student对象被回收。

那么软引用可以用于哪些场景呢?

软引用可以用来实现内存敏感的 高速缓存 ,当系统空间不足时缓存对象可被清理掉而不影响业务。

弱引用

如果触发GC,这时内存很充足,但是被弱引用的对象还是会被回收。所以说,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。

运行结果

 before gc: r=I'm here,  static =I'm here
 after  gc: r=null, static=I'm here
  

如果是被WeakReference包裹的对象,那么这个对象就是被弱引用的。我们看到GC后r.get=null。但是sr.get()还是有值的。如果被包裹的数据是静态的,即便被弱引用,也不会被GC回收的。

其实 ThreadLocal 里面也运用到了弱引用哦。具体可以看看我之前的一篇文章:

虚引用

这就是虚引用有几个特点:

  • 无法通过虚引用来获取对一个对象的真实引用。
  • 虚引用必须与ReferenceQueue一起使用,当GC准备回收一个对象,如果发现它还有虚引用,就会在回收之前,把这个虚引用加入到与之关联的ReferenceQueue中。

运行结果:

 null
  

那么给对象设置成虚引用有什么用呢?

为一个对象设置虚引用关联的唯一目的就是能在这个对象被垃圾收集器回收时收到一个系统通知。

还有会用虚引用管理堆外内存。

文章来源:智云一二三科技

文章标题:Java中的强软弱虚,你了解么?

文章地址:https://www.zhihuclub.com/198220.shtml

关于作者: 智云科技

热门文章

网站地图