我试图了解课堂 ReferenceQueue
它是的可选构造函数参数
SoftReference
和
WeakReference
这也是的强制性参数PhantomReference
。
根据我已阅读的信息,我可以写一些论文
a)对于PhantomReference方法,get始终返回null
b) 对于Phantom引用:
1. gc检测到可以从内存中删除
该对象2.
当我们从队列中调用clear或link到引用的引用时,引用了放置到ReferenceQueue的对象,因为无法访问并且gc看到了3.
finalize方法调用
4。
弱/软引用的 可用内存 :
1. gc检测到可以从内存中删除对象
2. finalize方法调用
3.空闲内存
4.对放入队列的对象的引用
XXXReference
构造函数?PhantomReference
没有构造函数ReferenceQueue
呢?也许以下程序会有所帮助:
public class SimpleGCExample {
public static void main(String[] args) throws InterruptedException {
ReferenceQueue<Object> queue=new ReferenceQueue<>();
SimpleGCExample e = new SimpleGCExample();
Reference<Object> pRef=new PhantomReference<>(e, queue),
wRef=new WeakReference<>(e, queue);
e = null;
for(int count=0, collected=0; collected<2; ) {
Reference ref=queue.remove(100);
if(ref==null) {
System.gc();
count++;
}
else {
collected++;
System.out.println((ref==wRef? "weak": "phantom")
+" reference enqueued after "+count+" gc polls");
}
}
}
@Override
protected void finalize() throws Throwable {
System.out.println("finalizing the object in "+Thread.currentThread());
Thread.sleep(100);
System.out.println("done finalizing.");
}
}
在我的系统上,它会打印
weak reference enqueued after 1 gc polls
finalizing the object in Thread[Finalizer,8,system]
done finalizing.
phantom reference enqueued after 2 gc polls
要么
finalizing the object in Thread[Finalizer,8,system]
weak reference enqueued after 1 gc polls
done finalizing.
phantom reference enqueued after 2 gc polls
由于多线程,前两个消息的顺序有时会有所不同。有时,幻象引用被报告在三个轮询之后加入队列,这表明它花费了超过指定的100毫秒的时间。
关键是
finalize
方法,否则在对象再次变得不可访问之后将它们排队finalize()
方法的存在导致需要至少一个额外的垃圾收集周期来检测对象不可达或幻像可达由于所有对象中超过99%的对象不需要完成,因此强烈建议所有JVM供应商检测何时finalize()
未被覆盖或“琐碎”,即空方法或单独super.finalize()
调用。在这些情况下,应该省略最终确定步骤。通过删除finalize()
上面示例中的方法,您可以轻松检查此优化是否在JVM中发生。然后打印
weak reference enqueued after 1 gc polls
phantom reference enqueued after 1 gc polls
由于两者都立即入队并以任意顺序检索,因此这两个消息的顺序可能会有所不同。但是它们总是在一个gc周期后都被排入队列。
值得注意的是,幻像引用不会自动清除,这意味着它需要另一个垃圾回收周期,直到对象的内存真正可以重用为止,因此上面的示例至少需要三个周期(使用非平凡finalize()
方法),两个不使用。Java
9将对此进行更改,自动清除幻像引用,因此在上面的示例中,将需要两个周期进行最终确定,而一个周期直到真正可以回收内存为止。好吧,准确地说,在这个简单的示例中,对象的内存将永远不会被回收,因为程序会在此之前终止。
上面的代码还演示了Reference
API的预期用例之一。我们可以使用它来检测对象的可访问性何时在我们的完全控制下的代码中更改,例如,使用main
方法内的循环。相反,finalize()
可以在任意时间由不同的未指定线程调用。该示例还显示,您可以从参考对象中提取信息,而无需使用该get()
方法。
实际应用程序经常使用引用类的子类向它们添加更多信息。这就是WeakHashMap.Entry
扩展WeakReference
和记住哈希码和值的过程。清理可以在常规映射操作中完成,不需要任何线程同步。finalize()
除了地图实现无法将finalize()
方法推入键类之外,使用方法是不可能的。
这意味着“比完成更灵活”一词。
该WeakHashMap
演示了get()
方法是有用的。只要尚未收集密钥,就会将其报告为在地图中,并且可以在遍历所有密钥或条目时进行检索。
该PhantomReference.get()
方法已被覆盖以始终返回,null
以防止应用程序可以重新占用已排队引用的引用。这是“虚拟引用不会自动清除”规则的直接结果。该规则本身令人怀疑,其初衷是在黑暗中。虽然该规则将在下一个Java版本中进行更改,但是恐怕get()
它将继续返回null
向后兼容。
问题内容: 做和何时为实例变量创建真的只有帮助?在方法范围内使用它们有什么好处? 另一个重要部分是。除了能够跟踪确定垃圾的引用之外,还可以用于强制注册对象以进行垃圾回收吗? 例如,是否值得创建一个方法,该方法在对象中占用一些沉重的内存资源(由强引用保存),并创建引用以将它们排入队列? (想象一下,在这种情况下,Object代表使用大量内存的对象类型…诸如此类) 这有现实效果吗?还是这只是浪费代码?
问题内容: 我想在其他线程不再引用它时正确关闭Closeable对象。 我写了一些小测试,但是将对象加入队列后,get方法返回null,即poll方法返回没有引用的正确Object。 提前致谢。任何帮助将不胜感激。 问题答案: 首先,如果仅是关闭,请使用。接下来,从参考队列中,不保证您将获得参考。并且您将永远不会找回实际的对象(参考对象)。 如果要确保已关闭,则必须自己跟踪它们。然后,当您使用参考
问题内容: 我在Android源代码中看到一个陌生的符号: 例如: 我对星号表示法不熟悉。有人可以解释吗? 问题答案: 是的简化版本 此表示法来自C。
问题内容: 我想知道我是否使用值为8的INT,这是否意味着我只能从1到99999999或从1到4294967295 UNSIGNED? 问题答案: 该文档对此似乎很清楚: 数值类型属性 MySQL支持扩展,可以选择在整数类型的基本关键字之后的括号中指定整数数据类型的显示宽度。例如,INT(4)指定显示宽度为四位数的INT。应用程序可以使用此可选的显示宽度来显示整数值,该整数值的宽度小于为列指定的宽
问题内容: 我正在写一个类,表示一个二维向量。我存储和在。 当要求生成和时,eclipse生成了以下内容: 什么是意义在这方面?我不能简单地写吗? 问题答案: 简短答案:Eclipse使用 Double.doubleToLongBits, 因为这就是Double.equals的作用: 结果是,当且仅当参数不是,并且是一个Double对象,该对象表示与该对象表示的值相同的e 。为此,当且仅当该方法应
我一直在网上关注关于SQLite的android教程。我有一份声明,我不确定: 在这个方法中,意味着什么?它是当前对象还是上下文?谢谢