关于Java中可终结对象的讨论通常讨论当可终结对象(及其关联资源)无法快速垃圾收集时发生的常见间接成本。一个对象可以终结的前期成本是多少?
我现在更感兴趣的是,在内存条件和对象分配时间中,实际可终止的直接成本是多少。我已经看到了在一些地方这种成本的存在,拐弯抹角例如,Oracle's article on finalization memory retention issues注:
当
obj
分配,在JVM内部记录了obj
是终结。这通常会减慢现代JVM具有的快速分配路径。
JVM如何记录一个对象实例是否可终止,以及这样做的内存和性能成本如何?
对于那些有兴趣在我的具体应用:
我们生产和保留数百万难以置信的轻量级的对象;向这些对象添加单个指针的代价非常高昂,所以我们已经做了一些工作来删除指针,而不是使用打包到字段子集中的较小数字ID。将数字解包允许从使用Map存储它们的Pool中检索具有该ID的共享不变属性。
剩下的问题是如何处理不再使用的属性值的垃圾回收。
一个已经考虑的策略是使用引用计数;当创建对象并检索某个值的共用标识时,该值的引用计数会递增;当它不再使用时,它必须递减。确保这一点递减
一种选择的情况是添加下面的finalize方法:
public void finalize() {
Pool.release(getPropertyId());
}
但是,如果被终结的这个行为意味着对对象的额外指针必须保持,上箭头这个应用程序的前端成本可以被认为是高的。如果这意味着必须分配额外的对象,那么它几乎肯定会太高......因此,我的问题是:可定稿的直接前期成本是多少?
是不是不好的做法,依靠的对象的终结?我的意思是,它不能保证'finalize()'会被调用 - 或者? – vikingsteve
您可能想要管理自己的对象池,而不是依靠JVM。根据您需要同时使用多少个对象,您可以通过完全避免分配/垃圾收集/最终化开销来发现巨大的性能提升。 –
您不应该创建这么多的可终结对象,这应该是一个问题。您应该只将它作为最后的手段使用,否则清理对象时会发现严重的性能/稳定性问题。你可能不会担心,但是使用这个很多,你会。 –