适用于PhantomReference的 Javadoc 8 指出:
与Java终结机制相比,虚拟引用最常用于以更灵活的方式调度事前清理操作。
因此,我尝试创建一个线程,该线程正在调用close()符合垃圾回收条件的Test Object方法。在run()试图获得所有测试对象的预验。
实际上,检索到的测试对象都是null。预期的行为是检索测试对象并调用该close方法。
无论创建多少个测试对象,都不会在验尸前捕获单个测试对象(您必须增加超时并多次调用GC)。
我究竟做错了什么?这是Java错误吗?
我试图创建一个最小,完整和可验证的示例,但是它仍然很长。我java version "1.8.0_121"在Windows 7 64位上使用32位。
public class TestPhantomReference {
public static void main(String[] args) throws InterruptedException {
// Create AutoClose Thread and start it
AutoCloseThread thread = new AutoCloseThread();
thread.start();
// Add 10 Test Objects to the AutoClose Thread
// Test Objects are directly eligible for GC
for (int i …Run Code Online (Sandbox Code Playgroud) java garbage-collection phantom-reference finalize finalizer
在Visual Studio中,当我键入行" Implements IDisposable"时,IDE会自动添加:
disposedValue成员变量Sub Dispose() Implements IDisposable.DisposeSub Dispose(ByVal disposing As Boolean)本Dispose()应单独留在家中,并清理代码应放在Dispose(disposing).
但是Dispose Finalize Pattern表示你也应该覆盖Sub Finalize()调用Dispose(False).为什么IDE也不添加这个?我必须自己添加它,还是以某种方式隐式调用?
编辑:任何想法为什么IDE自动添加80%的所需东西,但不包括Finalize方法?这种功能的重点不在于帮助您不要忘记这些事情吗?
EDIT2:谢谢大家的优秀答案,现在这完全合情合理!
调用System.gc()或finalize()方法时内部发生了什么(JVM)?
这真的是收集垃圾还是降低性能?
(1)我已经阅读了很多关于IDisposable的问题,其中答案建议不要使用Finalize,除非你真的需要因为涉及的处理时间.
我没有看到的是这笔费用是多少以及支付的频率.每毫秒?第二?小时,天等
(2)此外,在我看来,如果一个物体可以处理,并不总是知道Finalize是否方便.例如,框架字体类.控件无法处理它,因为它不知道字体是否共享.字体通常是在设计时创建的,因此用户不会知道处理它,因此最终确定踢,以便在没有引用时最终摆脱它.这是一个正确的印象吗?
我有一个带有telesize()方法的伸缩构造函数的超类.为了防止子类忘记调用super.finalize,我已经编写了一个终结器监护器(EJ Item 7).
public class Super {
public Super() {}
{
Object finalizerGuardian = new Object() {
@Override
protected void finalize() {
System.out.println("Finalizer guardian finalize");
Super.this.finalize();
}
};
}
protected void finalize() {
System.out.println("Super finalize");
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个示例子类 -
public class Sub extends Super {
public Sub() {}
protected void finalize() {
System.out.println("Sub finalize");
}
public static void main(String[] args)
throws InterruptedException {
if (1 == 1) {
Sub s1 = new Sub();
}
Runtime.getRuntime().gc();
Thread.sleep(10000);
}
}
Run Code Online (Sandbox Code Playgroud)
当s1对象超出范围时,终结器监护人的finalize()被调用,我从子类的finalize方法中获取SYSO,但从未从super的finalize中获取.
我糊涂了.我是否从根本上误解了一些事情? …
这是我的代码
public class FinalizableObject {
@Override
protected void finalize() throws Throwable {
System.out.println("finalize() invoked for " + this);
super.finalize();
}
}
public class Main {
private static void test() throws InterruptedException {
ReferenceQueue<FinalizableObject> rq = new ReferenceQueue<FinalizableObject>();
FinalizableObject obj = new FinalizableObject();
PhantomReference<FinalizableObject> pr1 = new PhantomReference<FinalizableObject>(obj, rq);
obj = null;
System.gc();
Reference<? extends Object> ref = rq.remove();
System.out.print("remove " + ref + " from reference queue\n");
}
public static void main(String[] args) {
try {
test();
} catch (InterruptedException …Run Code Online (Sandbox Code Playgroud) SCJP 6学习指南引用:
在该
finalize()方法中,您可以编写将对相关对象的引用传递回另一个对象的代码,从而有效地使对象无法进行垃圾回收.如果稍后在同一个对象上再次符合垃圾回收条件,垃圾收集器仍然可以处理该对象并将其删除.但是,垃圾收集器会记住,对于此对象,finalize()已经运行,并且它不会finalize()再次运行
它为什么这么设计?finalize()即使第二次将对象标记为集合时,该方法的目的仍然保持良好.那为什么Java决定跳过调用finalize()?
在迁移到Kotlinfrom 时Java我遇到了一个问题。我覆盖了Object的finalize()方法:
@Override
protected void finalize() throws Throwable {
stopTimer();
super.finalize();
}
Run Code Online (Sandbox Code Playgroud)
当我尝试用 Kotlin 做同样的事情时,我找到了解决方案。第一个来自文档:
protected fun finalize() {
stopTimer()
super.finalize()
}
Run Code Online (Sandbox Code Playgroud)
文章中的第二个(俄语):
@Suppress("ProtectedInFinal", "Unused")
protected fun finalize() {
stopTimer()
super.finalize()
}
Run Code Online (Sandbox Code Playgroud)
但在这两种情况下,我都不能super.finalize()根据 IDE调用,正如它所说的unresolved reference:finalize
也许有人知道如何完成这项工作Kotlin?谢谢。
我有一个涉及多个类的 Java 11 项目。在当前场景中,我的 2 个类(A 和 B)实现了 java Finalize() 方法,该方法现已永久弃用。我知道该方法可能不会在不久的将来被删除,但我认为最好立即找到 Finalize 的替代方法。
A类中的finalize()主要关注于销毁一个受保护的成员变量long类型的对象,并将某些消息打印到日志中。B 类中的 Finalize() 只是将某些消息打印到日志中。
类 A 的实例是从其他几个类创建的,类 B 扩展了另一个类 ClassLoader。(下面包含代码片段。)
我经历了很多建议,例如,
这些一开始就没有得到很好的解释,即使解释得很好,这些示例也特定于单类项目,并且主方法存在于同一类中。我无法继续使用我在网上找到的最小解决方案。
经过我的研究,带有 try-with-resources 的 Autocloseable 似乎是我的最佳选择。我知道我的类 A 和 B 应该实现 Autocloseable,而被调用者(这里有点不确定)应该使用 try-with-resources。
我将不胜感激任何有助于简化这个问题的帮助,即使它是为了填补我对这个场景的理解中可能存在的空白。
A.java
class A
{
protected long a_var;
protected A(String stmt, boolean isd)
{
// a_var is initialized here
}
public void finalize()
{
if(a_var != 0)
{
log("CALL destroy !");
destroy(a_var);
log("DONE destroy !");
}
} …Run Code Online (Sandbox Code Playgroud) 我的理解是像 ParallelGC 和 G1 这样的 GC 是“分代”收集器。垃圾收集几乎是作为副产品发生的,因为您将所有活动对象移动到新的堆区域,而旧区域中剩余的任何内容都将被简单地覆盖。这种“副产品”的解释很有意义,除了 Java 需要在死对象上调用 finalize() 的部分。Java 是否还保留每个堆区域中所有对象的单独列表,以便与活动对象进行比较?
finalize ×10
java ×7
idisposable ×2
vb.net ×2
.net ×1
c# ×1
deprecated ×1
destructor ×1
dispose ×1
finalizer ×1
g1gc ×1
heap-memory ×1
jvm ×1
kotlin ×1
reference ×1