6

维护对异常的引用以供以后使用是否合理,或者是否存在将异常引用保持比 throw/catch 交互更长的时间的陷阱?

例如,给定代码:

class Thing {
  private MyException lastException = ...;
  synchronized void doSomethingOrReportProblem() {
    try {
      doSomething();
    } catch (MyException e) {
      if (seemsLikeADifferentProblem(e, lastException)) {
        reportProblem(e);
      }
      lastException = e;
    }
  }
}

假设我的程序创建了一个生命周期与 JVM 一样长的事物,那么在维护对 lastException 的挥之不去的引用的事物中是否存在任何正确性问题?这在JDK7中是否发生了变化?(查看 OpenJDK7 中 Throwable 的源代码,似乎有一个新的四参数公共构造函数,它不在 JDK6 中,它可以创建 Throwable 而无需在构造时调用 fillInStackTrace()。)

如果 MyException 下的任何链接异常都引用了对象,是的,这将阻止这些对象被垃圾收集,但假设我对此没问题,是否有任何陷阱需要提防?

4

3 回答 3

0

我建议您基本上应该像对待任何带有“后端本机代码/存储”的对象一样对待它。如果您需要保留对一些异常的引用,例如“记住”从哪里调用特定方法等,那么不要害怕这样做。另一方面,不要在没有以某种方式“监控情况”的情况下继续使用数十万个。

于 2012-11-14T19:28:04.330 回答
0

Throwable 是一个成熟的 Java 对象,只要有人引用它,它就会一直存在。自从我进入 Throwable 以来已经有一段时间了,但我想不出它可能会保留对堆栈跟踪中方法类以外的引用(只是可能)。然而,堆栈跟踪本身确实消耗了大量的存储空间。

所以它真的和任何其他中等大的物体没有什么不同。在 JVM 的整个生命周期中保留一个例外似乎一点也不奇怪。(如果您保留所有异常的记录,那可能有点多。)

于 2012-11-14T20:04:06.927 回答
0

有 2 种常见情况下,对异常的引用超出了它们的直接程序相关性:

  1. 当被传递给日志框架时
  2. 当被传播出容器上下文时,通常在适应合适的形式后返回到远程应用程序
于 2012-11-14T22:37:11.963 回答