【问题标题】:Java equivalent of GC.SuppressFinalizeGC.SuppressFinalize 的 Java 等价物
【发布时间】:2014-05-22 04:40:25
【问题描述】:

Java 是否有 .Net 的 GC.SuppressFinalize 等价物?

在 .Net 中,只要明确处置对象,在 dispose pattern 中使用 SuppressFinalize 即可避免终结的 relatively high performance cost。类似的成本适用于 Java,但它似乎没有 SuppressFinalize。

我知道通常最好完全避免使用终结器,但我认为我不能在我的特定用例中避免使用它们(取消标记,您可以在其中添加仅在另一个标记未取消时才运行的处理程序,因此由于其来源被收集而变得不朽的令牌必须导致条目从链接的令牌中删除,以免它们无限制地累积垃圾条目。

Java 中是否存在与 SuppressFinalize 等效的功能?如果不是,是否可以使用可用的工具(例如ReferenceQueue)进行近似?

【问题讨论】:

标签: java .net garbage-collection finalizer


【解决方案1】:

我想出了一个可能的解决方法,因为在 Java 中没有等效方法,只要避免终结器的成本即可:使用缓存。

  1. 拥有一个带有可变回调成员的对象:

    public final class Finalizer {
      public Runnable onFinalizer;
      @Override
      protected void finalize() {
        if (onFinalizer != null) {
          onFinalizer.run();
        }
      }
    }
    
  2. 收集它们:

    Stack<Finalizer> finalizerCache = new Stack<>();
    
  3. 在需要时抓住:

    this.finalizer = finalizerCache.isEmpty() ? new Finalizer() : finalizerCache.pop();
    this.finalizer.onFinalizer = () -> { my special cleanup code; };
    
  4. 需要时丢弃:

    void cancel() {
      this.finalizer.onFinalizer = null;
      if (finalizerCache.size() < 100) {
        finalizerCache.push(this.finalizer);
      }
      this.finalizer = null;
    }
    

显然,可能会有很多与缓存大小及其同步方式相关的调整,但这应该是一种有用的方法,可以在终结器很少运行且没有太多流失的情况下避免终结器成本在需要完成的对象总数中。

【讨论】:

    【解决方案2】:

    Java 没有原生的“GC.SuppressFinalize”方法。但是 IDiposable 模式将有助于您解决这个问题。

    您可以在您知道不再需要某个物品时手动处置该物品或 能够运行清理代码以安全地关闭连接、关闭文件等。此外,您将 能够使用终结器来捕获不知道何时应该清理对象的情况。

    【讨论】:

      猜你喜欢
      • 2012-06-03
      • 2013-01-15
      • 1970-01-01
      • 2010-11-13
      • 2019-11-03
      • 2011-01-16
      • 1970-01-01
      • 2016-07-16
      • 2011-10-06
      相关资源
      最近更新 更多