尽管WeakReference没有调用finalize()方法

问题描述:

我目前对一个没有调用finalize()方法的类的对象存在问题,尽管只存储在作为值的ConcurrentHashMap中,而对象的UUID作为键地图。尽管WeakReference没有调用finalize()方法

这里是我创建了一个例子(它不是在我的实际项目中使用的一个,但这个例子中也没有调用的对象finalize()方法。

TestMain.class //主类处理HashMap中

public class TestMain { 

public static ConcurrentHashMap<String, WeakReference<Test>> map = new ConcurrentHashMap<String, WeakReference<Test>>(); 

    public static void main(String args[]) { 
    map.put("Key1", new WeakReference<Test>(new Test("test 1", 2))); //This "Test" Object shouldn't be accessible anywhere besides the HashMap anymore, and therefore I want it to be "finalized" by the garbage collector. 
    System.out.println("DONE"); 
    } 
} 

的Test.class //对象类

public class Test { 
    public String string; 

    public int intt; 

    public Test(String string, int intt) { 
    this.string = string; 
    this.intt = intt; 
    } 

    @Override 
    protected void finalize() throws Throwable { 
    System.out.println("FINALIZED TEST CLASS: " + string); 
    super.finalize(); 
    } 
} 

当运行的主要方法,所有的被印刷为 “DONE” 时我人口会d“FINALIZED TEST CLASS:Test 1”也可以在此之前打印。我的代码有什么问题,或者我误解finalize()的工作原理?

另外,我想这个工作,我解释一下,因为我需要与finalize()方法的对象从“地图” Map从记忆中抹去一样会有我的项目运行过程中产生的对象的几百持续时间,所以我希望不再使用的对象被清除,为更多新对象腾出空间。

编辑:我看到互联网上的其他地方,人们说程序可能在垃圾回收器有机会处理上述对象之前终止。因此,我试图通过添加一个简单的while(true){}循环来让我的程序不终止,并等待了几分钟,但仍然没有看到该对象正在“完成”的消息。

任何帮助非常感谢,谢谢。

+4

无法保证finalize方法将被称为 – Pragnani

+0

@PragnaniKinnera那么,我将如何手动处理这些对象后,他们不能在其他地方访问?我现在很困惑 –

+1

@C_Beth这不是你的工作,GC会照顾到这一点。当你尝试自己做这件事会引起额外的烦恼 – Pragnani

正如在评论中提到的那样,不能保证调用finalize方法。

Java编程语言不能保证哪个线程将 调用任何给定对象的finalize方法。但是,保证, 然而,当调用finalize时,调用finalize的线程将不会保留任何 用户可见的同步锁。如果finalize方法引发了 未捕获的异常,则忽略 异常,并终止该对象的终止。

现在回来到您的他们不再访问后这些对象手动配置的关注,你不需要搞定,Java垃圾收集器会处理,对于你与它的自动内存管理。如果你想加快垃圾收集,请阅读G1垃圾收集器。

+0

好的谢谢;我不知道GC只会在需要时自动运行。 –

最可能的解释是GC从未跑过。

  • 如果GC没有运行,那么对象不会被垃圾收集。

  • 如果没有收集到对象,它们将不会被最终确定。

试图让我的程序不是通过把一个简单而(真){}循环终止并等待一两分钟,

等待GC不会帮帮我。通常它只在需要运行< <时运行;即,当其中一个堆空间超过充满阈值时。

您可以通过调用System.gc()来强制GC运行...但是这是不良做法。它会使您的应用程序效率低下且无法响应。

尝试在终结器中做任何事情都是不明智的,必须及时完成。您应该设计自己的代码,以便:

  • 它不一样,如果一个对象从来没有得到所有定稿无所谓了,
  • 也不要紧,当一个对象被敲定。

为什么?因为你几乎无法控制什么时候对象被完成......而且如果你不打电话给System.gc() ......你根本不应该这样做;往上看。

实际上,终结器是Java的一个特性,应该很少使用,如果有的话。唯一有效的用例涉及释放与应用程序尚未整理的资源对象相关的外部资源。即使如此,应用程序最好使用“尝试使用资源”(或finally块)来明确清理资源。

+0

http://prntscr.com/a8w7rq添加了'System.gc()',它证明当GC被调用时它将全部正常工作。谢谢 –