闲谈Java引用
| 本文总阅读量次Java语言对对象的引用有如下四种:强引用(StrongReference)、 软引用(SoftReference)、虚引用(PhantomReference)、 弱引用(WeakReference)。
1. 强引用(StrongReference)
Java中最常见的引用方式。当一个对象被一个或者一个以上的引用变量引用时,它处于激活状态,不可能被系统垃圾回收机制回收。
2. 软引用(SoftReference)
软引用需要通过SoftRefrence类来实现,当一个对象只具有软引用时,可能被垃圾回收机制回收。当系统内存空间足够时,它不会被系统回收,当系统内存空间不够时,系统将会回收。
和弱引用的区别仅仅在于垃圾回收时, 是否根据空间大小回收的区别。
何时回收软引用的对象?
从1.3.1开始软可达对象将在最后被引用之后存活一段时间。默认值是堆中每MB空闲空间一秒的生存时间。这个值可以使用-XX:SoftRefLRUPolicyMSPerMB
调整。
Java Hotspot服务端虚拟机使用最大可能的堆大小计算剩余可用空间。
Java Hotspot客户端虚拟机使用当前堆大小计算空闲空间。
这就意味着对于服务端虚拟机总体趋势是增长堆而不是清理软引用,因此在垃圾回收时-Xmx
对软引用的回收有重要的影响。
相反,客户端虚拟机将很大趋势去清理软引用而不是增长堆。
上述行为对于1.3.1到Java SE 6版本的Java HotSpot VM都是正确的。但是,此行为不是VM规范的一部分,并且在将来的版本中可能会更改。同样,不保证-XX:SoftRefLRUPolicyMSPerMB标志在任何给定的发行版中均不存在。
在1.3.1版之前,Java HotSpot VM会在发现软引用时清除它们。
当我定期打开-verbose:gc时,我得到了很多完整的GC,已经调整了堆并且没有什么区别,这是怎么回事?
如果您使用的是RMI,则可能会遇到分布式GC。另外,某些应用程序添加了显式GC的思想,即它将使它们的应用程序更快。幸运的是,您可以在1.3及更高版本中使用命令行选项禁用此功能。尝试将-XX:+ DisableExplicitGC与-verbose:gc一起使用,看看是否有帮助。
3. 虚引用(PhantomReference)
虚引用通过PhantomReference实现,虚引用类似于完全没有引用,虚引用对对象本身没有太大的影响。虚引用主要用于跟踪对象被垃圾回收的状态,虚引用不能单独使用,虚引用必须和引用队列(ReferenceQueue)联合使用。
举例来说就是,如果垃圾回收时,发现一个实例对象除了虚引用外没有任何其他的引用,将会把这个引用放到java.lang.ref.Reference.pending
队列里,GC完成时,通知ReferenceHandler这个守护线程做一些后续处理(如释放内存等等操作)。
4. 弱引用(WeakReference)
弱引用通过WeakReference类实现,对只有弱引用的对象而言,当系统垃圾回收机制运行时,不管内存是否足够,总会回收该对象所占用的内存。
4.1 示例
1 | ReferenceQueue referenceQueue = new ReferenceQueue(); |
ReferenceQueue的作用是为了查看哪些WeakReference和SoftReferece被回收了。
参考资料
- 本文链接: http://blog.programer.group/java/2019-09-15-reference/
- 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!