与Garbage Collector和finalize()方法相关的问题

时间:2014-03-14 11:37:27

标签: java c++ c garbage-collection

我正在阅读Java的垃圾收集和finalize()方法,并且有一些疑点引起了我的注意。对不起,如果你认为这些疑惑真的很傻。

  1. 我正在阅读文章http://javarevisited.blogspot.com/2011/04/garbage-collection-in-java.html。在这一点上,第5点说: '从内存中删除对象之前垃圾收集线程调用该对象的finalize()方法,并提供执行任何类型清理所需的机会'。 那么这件事肯定会发生吗?我的意思是在执行垃圾收集器方法之前总是调用finalize()方法吗?

  2. 垃圾收集器如何知道它需要执行?例如,我在服务器上部署了一个应用程序,那么GC什么时候执行?它会定期执行,还是会收集一些(比如1MB)垃圾并执行触发器或某些事情或它只是随机的并且无法确定何时执行?

  3. 由于垃圾收集没有发生,它如何降低我的应用程序的性能?

  4. 假设我的堆中有很多垃圾,但垃圾收集器没有被执行。如果发生这种情况,那么这不是一个坏行为或JVM的缺陷吗?

  5. 我们可以说在C / C ++中手动完成的垃圾收集比在Java中更好地考虑到我们作为程序员已经足够聪明并且知道什么时候我们需要处理'不那么引用' '指针?

3 个答案:

答案 0 :(得分:1)

  1. 在对象被垃圾回收之前,将始终调用finalize()方法。没有“垃圾收集方法”。

  2. 垃圾收集器会在它感觉到的时候运行。作为程序员,你无法控制它。从技术上讲,你可以通过制造大量垃圾或通过调用System.gc(),但你不需要。

  3. 垃圾收集器将在需要时运行。作为程序员,您不需要关心垃圾收集性能,但是有一些命令行选项可以调整垃圾收集器的行为。

  4. 如果内存不足而且垃圾收集器没有运行,那就是JVM漏洞。但它会运行。垃圾收集器将在需要时以及何时高效运行。如果在收集任何垃圾之前让堆充满垃圾更有效,那么它就会这样做。

  5. 这是一个非常主观的问题,双方都有充分的理由。 Java的垃圾收集减少了编程错误,但C和C ++的手动内存管理提供了更一致的性能和内存使用。

答案 1 :(得分:1)

  1. finalize()应该在对象清理之前发生。问题是 - 你不知道它什么时候会发生(如果它会发生的话)。不要指望finalize清理,只是在对象失去其范围之前自己进行清理。另请注意,finalize()在垃圾回收周期中运行。这意味着如果你实现finalize你的被动对象需要2个周期来清理,这意味着浪费了可以清理的内存。还有更多的CPU用于运行finalize并且您不知道何时。如果你有很多具有finalize的对象,那么他们可能会在GC期间一起运行,这可能会暂停整个应用程序很长一段时间

  2. 您可以调整不同的算法来确定垃圾收集何时发生。此外,它还取决于您分配给JVM的堆大小(以及其他参数,例如旧的与新生成大小,幸存者空间大小等等)。如果您正在处理小型应用程序 - 通常默认配置就足够了。如果您正在编写大型应用程序并且需要考虑一段时间内的性能,CPU时间和暂停时间(有时候GC会暂停整个应用程序) - 那么您最好先阅读堆内存模型以及不同的GC算法和参数可以调整以控制GC以更好地满足您的需求。

  3. 您的应用程序性能会受到GC周期的影响(不会发生GC周期)。例如 - 如果你的堆太小,你会经常出现循环。如果你的堆太大,你的循环次数会减少,但每次循环可能需要更长的时间来执行。同样,这些都取决于您选择的GC算法和调整参数以及堆内存分配(年轻代有多少内存,老代有多少,幸存者空间比等等......)

  4. 除非有足够的空间来分配新对象,否则我没有看到你有很多垃圾并且没有收集的情况。当空间用完或即将耗尽时(取决于您选择的收集算法以及堆大小和其他参数),将有一个集合。

  5. Java垃圾收集器解决了程序员在非托管语言(例如CC++)中遇到的痛苦问题。它有其优点和缺点。当您需要绝对控制记忆时,您将使用C。如果您想更轻松地编写系统,并且不介意为GC分配一些额外的内存,并且与GC共享一些CPU时间,那么您可以更快地编写(也更强大 - 因为那里用java来减少内存泄漏和其他令人讨厌的事情。

答案 2 :(得分:1)

[1] finalize调用是垃圾收集的一部分。

[2]垃圾收集器的策略和调用是实现的细节。因此,这里没有答案。

[3,4]如果你有很多小垃圾,收藏家可能不会进行垃圾收集。如果这个“微小的”消息可能会浪费内存(我认为这是内存泄漏)。对象保存收集器不知道的内存(图像可能由一个微小的句柄/指向本机内存的指针表示)。

[5] C ++的概念非常不同(这里省略C)。析构函数可以在确定点执行以释放分配的资源(参见:RAII)。