如果不是父对象,那么在super.finalize()方法之后GC会在父对象上清除什么?

时间:2015-06-28 23:36:04

标签: java inheritance garbage-collection jvisualvm

我的问题是基于以下事实:

  • 每当我们创建一个子类时,即使调用了超类构造函数,也不会创建超类对象。
  • 如果在子类中定义了finalize()方法,则还必须调用super.finalize()。

这一切都很好。但是当我使用jvisualjvm时(在JDK安装的 / bin目录下 - 我没有看到任何超类对象实例的创建,并且正如我所期望的那样。不会创建超类对象当我们创建它的子类实例时。

  

我的问题:GC在超级班级的部分内容是什么?

如果您双击并打开jvisualjvm,您可以看到(如果您使用Thread.sleep(forEnoughTimeToCheck_jvisualjvm)暂停程序)...您将找不到那里的超类实例,只有子类。 ..可能只是参考。那么GC何时会清除超类引用?

  

我在SO上看过很多博客和帖子,但我还没有见过   他们解释了什么GC在超级课程中清除了什么。

2 个答案:

答案 0 :(得分:1)

没有(除了每个垃圾收集阶段的内部状态),但由于子类是它的超类的实例,因此终结器通常被链接(就像构造函数隐式调用supertoString同样如此)。 super类可能拥有的任何资源都应该是free并且也会收集垃圾。

答案 1 :(得分:1)

  

GC是否会清除超类引用?

没有引用超类实例的东西。有两个类,如

class Super {
    int a;
}

class Sub extends Super {
    int b;
}

new Sub()您获得的对象包含字段ab。所有这些超类内容仅在某些地方很有趣,比如访问sub.ainstanceof支票。

  

每当我们创建一个子类时,即使调用了超类构造函数,也不会创建超类对象。

是....像new Sub()这样的电话会做三件事:

  • 它为一个足够大的对象分配空间,以容纳两个int s
  • 通过调用Super#Super
  • 的代码初始化其中的一部分
  • 通过调用Sub#Super
  • 的代码初始化其中的一部分

super()构造函数体中包含或隐含的对Sub的调用根本没有分配,只是初始化。

GC根本不关心。它所需要的只是知道对其他对象的引用在哪里(在我的例子中没有,因为只有原始字段)。

  

如果在子类中定义了finalize()方法,则还必须调用super.finalize()。

finalize是一种特殊的方法,可以进行特殊处理,但同样,如果Sub#finalize覆盖Super#finalize,则后者变得无关紧要(除非从前者明确调用,否则它应该,但这是另一个故事。)

请注意finalize很少使用,也许是百万的一个对象。你不应该覆盖它,除非你知道你真的需要它。它不是GC的基础。