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

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

点击上方蓝字关注我!




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

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

强引用

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

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

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

StrongReference类被回收了!!!

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

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

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

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

软引用

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

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

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

Student(grade=null)

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

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

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

运行结果

[B@7960847b
[B@7960847b
null

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

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

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

弱引用

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

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

运行结果

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

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

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

使用ThreadLocal怕内存泄漏?那你应该来看看这篇文章

虚引用

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

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

运行结果:

null

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

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

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




往期推荐




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

扫码二维码

获取更多精彩

Lvshen_9

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

原文始发于微信公众号(Lvshen的技术小屋):Java中的强软弱虚,你了解么?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/262491.html

(0)
Java朝阳的头像Java朝阳

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!