简体   繁体   English

你能指望.finalize()被调用吗?

[英]Can you count on .finalize() to be called?

I was attempting to instrument some of my Java code to ensure objects were being garbage collected correctly, and I found that surprisingly it wasn't being called as often as I expected. 我试图检测我的一些Java代码以确保对象被正确地进行垃圾收集,并且我发现令人惊讶的是它并没有像我预期的那样经常被调用。

I am now wondering if this is because of faulty instrumentation or an actual memory leak I need to solve. 我现在想知道这是因为错误的仪器还是我需要解决的实际内存泄漏。 the VisualVM profiler seems to indicate the former. VisualVM分析器似乎表明了前者。

The situation of concern is that I have a thread which handles requests and inside the request creates thousands of temporary objects. 令人担忧的情况是我有一个处理请求的线程,并且在请求中创建了数千个临时对象。 Sometimes, the socket this thread writes to is unexpectedly closed and the thread hits an exception and dies. 有时,此线程写入的套接字意外关闭,线程遇到异常并死亡。

When the Thread dies, it doesn't seem like .finalize() is ever called on those objects. 当线程死亡时,似乎不会在这些对象上调用.finalize()。 Is this a reason to not trust my instrumentation? 这是不相信我的仪器的原因吗?

Finalize() is not the solution. Finalize()不是解决方案。 You cannot know when finalizer will be called if any. 您无法知道何时会调用终结器。 If your problem is exception use try/catch/finally blocks and close/clean all stuff you want to close in finally block. 如果您的问题是异常,请使用try/catch/finally块并关闭/清除您要在finally块中关闭的所有内容。 This guarantees that everything will be cleaned in both cases: the logic terminated normally or exception was thrown. 这保证了在两种情况下都会清理所有内容:逻辑正常终止或抛出异常。

No. There is no guarantee that it will be called. 不,不能保证会被呼叫。 However, it is usually called. 但是,它通常被称为。 It may be that you are not properly releasing your objects, or the garbage collector has not run, or the finalizer thread is waiting for a good time to run. 可能是您没有正确释放对象,或者垃圾收集器没有运行,或者终结器线程正在等待运行的好时间。

You can read about it in the Finalization of Class Instances portion of the language spec. 您可以在语言规范的“类实例最终化”部分中阅读它。

According to all I read on Java basics you should never rely on finalize to be run. 根据我的所有关于Java基础读你应该依靠最后确定运行。 finalize() is not a destructor you may know from other languages. finalize() 不是你可能从其他语言中知道的析构函数

From java.lang.Object javadoc: 来自java.lang.Object javadoc:

The Java programming language does not guarantee which thread will invoke the finalize method for any given object.

http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#finalize () http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#finalize ()

The way I see things, the dreaded finalize should and is only used if you include some native code in your app. 我看待事物的方式,可怕的终结应该只在您的应用程序中包含一些本机代码时使用。 But even then be sure not to rely on it. 但即使这样,也要确保不要依赖它。

Your confusion seems to be whether there is a memory leak or not. 您的困惑似乎是内存泄漏是否存在。 You are trying to establish this by looking at whether finalize() was called or not. 您正试图通过查看是否调用finalize()来建立此功能。 If that is so then it's the not the correct to check whether there is a memory leak or not. 如果是这样那么检查是否存在内存泄漏是不正确的。

Just so we're clear, in Java, memory leaks mostly mean hidden references to objects you don't need. 我们很清楚,在Java中, 内存泄漏主要是指对您不需要的对象的隐藏引用。

Purpose of finalize() to give an opportunity to developer to clean up his own mess (connections, streams, ...). finalize()目的是让开发人员有机会清理自己的混乱(连接,流,......)。 Memory is supposed to be JVM's mess/headache and cleaned up by GC. 内存应该是JVM的混乱/头痛,并由GC清理。

So in short, fact that " GC guarantees to call finalize() before is frees memory ", shouldn't be interpreted as " if finalize() is not called there is a memory leak ". 简而言之,事实上“ GC保证在调用finalize()之前释放内存 ”,不应该被解释为“ 如果没有调用finalize()则存在内存泄漏 ”。 It could simply be that that object is not yet garbage collected. 可能只是该对象尚未被垃圾收集。

If you're looking to find memory leak use a tool. 如果您正在寻找内存泄漏,请使用工具。 See options: 见选项:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM