[英]what to use instead of finalize() in java
让我们考虑以下代码:
class Table {
private static int number_of_Tables=0;
public Table(){
++number_of_Tables;
}
public void finalize(){
--number_of_Tables;
}
public static int current_TableCount(){
return number_of_Tables;
}
}
我想要实现的是,当垃圾收集器 (GC) 销毁对象时,可用对象的数量会减少 1。
但是这里关于finalize()
主题的每个人都说使用这种方法非常糟糕,因为可能会发生以下情况:即使没有指向对象的引用,GC 也可能不会立即销毁它,因为 GC 不会全天候工作,即GC 将在一定数量的对象被销毁后被调用,即在某些时间 GC 将执行清理,这意味着即使对象不再可用,我的计数器也不会减少,并且我会在调用时提供错误信息方法curret_TableCount()
人们怎么做才能确定地解决此类问题?
Java中一定有某种解决方案吗?
编辑:我需要识别何时不再引用对象,即在运行时,当这是真的时,甚至不存在指向该对象的一个指针(引用),然后我会将此类对象的数量减少 1。
…可能会发生以下情况:即使没有指向对象的引用,GC 也可能不会立即销毁它,因为 GC 不会全天候工作
没错。 垃圾收集器的目的是管理内存并且只管理内存。 只要没有内存需求,垃圾收集器就不需要运行。 当有足够的内存时,应用程序完全有可能在没有任何 gc 循环的情况下完全运行。
此外,无法保证垃圾收集器运行识别所有无法访问的对象。 当它识别出足够多的可回收内存以允许应用程序继续时,它可能会停止工作。
然而,这并不是唯一的问题。 经常被忽视的是,垃圾收集器只关心内存需求,这意味着即使在使用对象时,当不再需要其内存时,也可能会收集对象,这可以通过优化代码实现。 这不是一个理论问题。 例如,请参阅此错误或与对终结的幼稚依赖相关的错误,即使在 JDK 代码中也是如此。
请注意,即使finalize()
恰好在正确的时间被调用,它也会被未指定的线程调用,这需要使用线程安全构造。
人们怎么做才能确定地解决此类问题?
一般人不会有这种问题。 如果你真的管理一个非内存资源,你应该使用显式的清理操作,即像dispose()
或close()
这样的方法,在使用后调用。 直接的方法是让类实现AutoClosable
(或其子类型)并使用try-with-resources 语句。
垃圾收集器触发的清理操作只是处理忘记显式清理的情况的最后手段。 如前所述,实施它们需要特别小心。
如果计数器仅用于统计数据,您可能会接受它不精确的事实。 通常,您不需要知道一个类存在多少个实例。 如果您确实需要它,例如在尝试调试内存泄漏时,您可以进行堆转储、所有现有对象的快照,并使用专用分析工具。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.