java.lang.ref.WeakReference和java.lang.ref.SoftReference有什么区别?
当前回答
为了给出一个动态内存使用方面,我做了一个实验,在重物的重负载下,将强、软、弱和幻影引用保留到程序结束。然后监控堆使用和GC行为。这些指标可能因情况而异,但肯定能提供高层次的理解。以下是调查结果。
重负载下的堆和GC行为
Strong/Hard Reference - As program continued, JVM couldn't collect retained strong referenced object. Eventually ended up in "java.lang.OutOfMemoryError: Java heap space" Soft Reference - As program continued, heap usage kept growing, but OLD gen GC happened hen it was nearing max heap. GC started bit later in time after starting program. Weak Reference - As program started, objects started finalizing & getting collected almost immediately. Mostly objects got collected in young generation garbage collection. Phantom Reference - Similar to weak reference, phantom referenced objects also started getting finalized & garbage collected immediately. There were no old generation GC & all objects were getting collected in young generation garbage collection itself.
你可以在这里获得更多关于这个实验的深度图表、统计数据和观察结果。
其他回答
为了给出一个动态内存使用方面,我做了一个实验,在重物的重负载下,将强、软、弱和幻影引用保留到程序结束。然后监控堆使用和GC行为。这些指标可能因情况而异,但肯定能提供高层次的理解。以下是调查结果。
重负载下的堆和GC行为
Strong/Hard Reference - As program continued, JVM couldn't collect retained strong referenced object. Eventually ended up in "java.lang.OutOfMemoryError: Java heap space" Soft Reference - As program continued, heap usage kept growing, but OLD gen GC happened hen it was nearing max heap. GC started bit later in time after starting program. Weak Reference - As program started, objects started finalizing & getting collected almost immediately. Mostly objects got collected in young generation garbage collection. Phantom Reference - Similar to weak reference, phantom referenced objects also started getting finalized & garbage collected immediately. There were no old generation GC & all objects were getting collected in young generation garbage collection itself.
你可以在这里获得更多关于这个实验的深度图表、统计数据和观察结果。
唯一真正的区别
根据文档,松散的weakreference必须由正在运行的GC清除。
根据文档,在抛出OOM之前必须清除松散的softreference。
这是唯一真正的区别。其他的都不是合同的一部分。(我假设最新的文件是合同文件。)
软引用很有用。内存敏感的缓存使用软引用,而不是弱引用。 WeakReference的唯一正确用法是观察GC运行。为此,您可以创建一个新的WeakReference,其对象立即超出作用域,然后尝试从weak_ref.get()中获取null。当它为空时,您可以了解到在此期间GC运行了。
关于WeakReference的错误使用,列表是无限的:
a lousy hack to implement priority-2 softreference such that you don't have to write one, yet it doesn't work as expected because the cache would be cleared on every GC run, even when there is spare memory. See https://stackoverflow.com/a/3243242/632951 for phails. (Besides, what if you need more than 2 levels of cache priority? You'd still gotta need a real library for it.) a lousy hack to associate data with an object of an existing class, yet it creates a memory leak (OutOfMemoryError) when your GC decides to take a break after your weakreferences are created. Besides, it's beyond ugly: A better approach is to use tuples. a lousy hack to associate data with an object of an existing class, where the class has the nerve to make itself non-subclassable, and is used in an existing function code which you need to call. In such a case, the proper solution is to either edit the class and make it subclassable, or edit the function and make it take an interface instead of a class, or use an alternative function.
在Java中;从强到弱依次为:强、软、弱、幻
强引用是一种普通引用,用于保护被引用的对象不被GC收集。即从不收集垃圾。
软引用可以被垃圾回收器收集,但可能直到需要它的内存时才会被收集。即在OutOfMemoryError之前进行垃圾收集。
弱引用是指不保护被引用对象不被GC收集的引用。即,当没有强或软引用时,垃圾收集。
幻影引用是在对象完成后,但在已分配的内存被回收之前,对对象的幻影引用。
源
类比:假设JVM是一个王国,对象是王国的国王,GC是王国的攻击者,试图杀死国王(对象)。
当国王强大时,GC不能杀死他。 当国王是软的,GC攻击他,但国王统治王国的保护,直到资源可用。 当国王虚弱时,GC攻击他,但在没有保护的情况下统治王国。 当国王是幻影时,GC已经杀死了他,但国王可以通过他的灵魂获得。
应该注意,弱引用对象只有在只有弱引用时才会被收集。如果它有一个强引用,那么无论它有多少弱引用,它都不会被收集。
软引用和弱引用之间唯一真正的区别是
垃圾收集器使用算法来决定是否 回收软可达对象,但总是回收弱可达对象 可访问的对象。
推荐文章
- Intellij IDEA Java类在保存时不能自动编译
- 何时使用Mockito.verify()?
- 在maven中安装mvn到底做什么
- 不可变与不可修改的集合
- 如何在JSON中使用杰克逊更改字段名
- GSON -日期格式
- 如何从线程捕获异常
- 无法解析主机"<URL here>"没有与主机名关联的地址
- 如何在Java中打印二叉树图?
- String.format()在Java中格式化双重格式
- com.jcraft.jsch.JSchException: UnknownHostKey
- Java中的操作符重载
- 如何加速gwt编译器?
- 在Hibernate中重新连接分离对象的正确方法是什么?
- 应该……接住环内还是环外?