首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Java中的强软弱虚,你了解么?

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

作者头像
Lvshen
发布2022-05-05 17:35:20
发布2022-05-05 17:35:20
2880
举报

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

强引用

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

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

代码语言:javascript
复制
StrongReference类被回收了!!!

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

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

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

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

软引用

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

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

代码语言:javascript
复制
Student(grade=null)

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

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

运行结果

代码语言:javascript
复制
[B@7960847b
[B@7960847b
null

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

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

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

弱引用

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

运行结果

代码语言:javascript
复制
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里面也运用到了弱引用哦。具体可以看看我之前的一篇文章:

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

虚引用

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

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

运行结果:

代码语言:javascript
复制
null

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

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Lvshen的技术小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 强引用
  • 软引用
  • 弱引用
  • 虚引用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档