在Java中,关于可终结对象的讨论通常会涉及当不可快速回收可终结对象(和它们相关的资源)时发生的常见间接成本。
目前,我更感兴趣的是可终结性实际的直接成本,包括内存方面和对象分配时间方面。我在许多地方看到了对这种成本存在的间接引用,例如Oracle的最终化内存保留问题文章中提到:
当分配
obj
时,JVM会在内部记录obj
是可终结的。这通常会减慢现代JVM具有的快速分配路径。
JVM如何记录对象实例为可终结对象,进行此操作的内存和性能成本是什么?
对于那些对我具体应用程序感兴趣的人:
我们生产并保留了数百万极轻量级的对象;添加单个指针到这些对象是非常昂贵的,因此我们已经做了很多工作来从中删除指针,而是使用打包在字段的子集中的较小数字 ID。解压缩该数字允许从存储它们的 Map 中检索具有该 ID 的共享不可变属性。剩下的问题是如何处理不再使用的属性值的垃圾回收。
考虑过的一种策略是使用引用计数;当创建对象并检索值的池化 ID 时,该值的引用计数将增加;当它不再使用时,必须将其减少。
确保发生此减量的一个选项是添加以下 finalize 方法:
public void finalize() {
Pool.release(getPropertyId());
}
然而,如果成为可终结对象的行为意味着必须保留对该对象的附加指针,则对于此应用程序来说,成为可终结对象的前期成本将被认为是高昂的。如果这意味着必须分配额外的对象,则几乎肯定过高...因此,我的问题是:成为可终结的直接前期成本是多少?
finalize()
方法从来没有保证会被调用,对吗? - vikingsteveWeakReference
,这样您就不会有任何额外的对象。但即便如此,与终结相比,该额外信息通常被认为是显著更便宜的。 - Louis Wasserman