我的问题是基于以下事实:
这一切都很好。但是当我使用jvisualjvm
时(在JDK安装的 / bin目录下 - 我没有看到任何超类对象实例的创建,并且正如我所期望的那样。不会创建超类对象当我们创建它的子类实例时。
我的问题:GC在超级班级的部分内容是什么?
如果您双击并打开jvisualjvm
,您可以看到(如果您使用Thread.sleep(forEnoughTimeToCheck_jvisualjvm)
暂停程序)...您将找不到那里的超类实例,只有子类。 ..可能只是参考。那么GC何时会清除超类引用?
我在SO上看过很多博客和帖子,但我还没有见过 他们解释了什么GC在超级课程中清除了什么。
答案 0 :(得分:1)
没有(除了每个垃圾收集阶段的内部状态),但由于子类是它的超类的实例,因此终结器通常被链接(就像构造函数隐式调用super
和toString
同样如此)。 super
类可能拥有的任何资源都应该是free
并且也会收集垃圾。
答案 1 :(得分:1)
GC是否会清除超类引用?
没有引用超类实例的东西。有两个类,如
class Super {
int a;
}
class Sub extends Super {
int b;
}
和new Sub()
您获得的对象包含字段a
和b
。所有这些超类内容仅在某些地方很有趣,比如访问sub.a
或instanceof
支票。
每当我们创建一个子类时,即使调用了超类构造函数,也不会创建超类对象。
是....像new Sub()
这样的电话会做三件事:
int
s Super#Super
Sub#Super
super()
构造函数体中包含或隐含的对Sub
的调用根本没有分配,只是初始化。
GC根本不关心。它所需要的只是知道对其他对象的引用在哪里(在我的例子中没有,因为只有原始字段)。
如果在子类中定义了finalize()方法,则还必须调用super.finalize()。
finalize
是一种特殊的方法,可以进行特殊处理,但同样,如果Sub#finalize
覆盖Super#finalize
,则后者变得无关紧要(除非从前者明确调用,否则它应该,但这是另一个故事。)
请注意finalize
很少使用,也许是百万的一个对象。你不应该覆盖它,除非你知道你真的需要它。它不是GC的基础。