gpt4 book ai didi

java - 在 log4j 中使用 fillInStackTrace() 会更便宜吗?

转载 作者:行者123 更新时间:2023-12-01 18:44:36 25 4
gpt4 key购买 nike

我在我的应用程序中使用 log4j,只是想知道我是否将 Exception 对象传递到记录器中,如 (1) 中所示,这是否会比我传递时消耗更多资源在e.fillInStackTrace()中,如(2)所示?换句话说,(2)会比(1)更便宜吗?下面是我在 log4j 上的示例代码。

private static Logger logger = Logger.getLogger(...);

try {
...
}
catch( Exception e ) {
logger.error("blah blah blah", e); // (1)

logger.error("blah blah blah", e.fillInStackTrace()); // (2)
}

我有点困惑,请帮忙澄清一下?

最佳答案

好吧,如果您查看 fillInStackTrace,您会注意到该方法是同步的。在 Java(或任何语言)中,同步被认为是一个相当昂贵的操作,因为它需要获取和释放监视器。

此外,您应该注意,从 fillInStackTrace 返回的 Throwable 仅记录有关 fillInStackTrace 当时调用堆栈的堆栈帧的信息叫做。该信息直接从 JVM 收集,然后转换为对象表示,这又会消耗资源。 (最终,fillInStackTrace 委托(delegate)给一个 native 方法,该方法扫描调用线程的当前调用堆栈。)

但是,您应该主要考虑要在日志中显示的内容,并根据该标准做出决定。当您显式调用 fillInStackTrace 时,当前 调用堆栈将出现在您的日志中。这意味着您将不会再看到进入 try block 的更深调用堆栈(考虑您的示例)。

毕竟,您应该始终使用变体(1),除非您明确需要通过(2)获得的信息。我无法自发地想到标准日志记录范围内的解决方案(2)有意义的示例。然而,当您编写某种框架并且想要清除一些与堆栈无关的顶部堆栈条目时,您可以使用(2)来消除堆栈跟踪中的噪音。异常:例如,您可能正在使用某种 ExceptionFactory 来为您创建抛出的异常。那么您不希望堆栈跟踪显示这些工厂方法的堆栈帧,因为它们与错误无关,并且会使尝试调试的用户感到困惑。因此,您可以在收到来自工厂的异常后通过调用 fillInStackTrace 手动填充堆栈跟踪。

查看此示例,直观地了解这两个调用的差异:

class Example {
public static void main(String[] args) {
try {
outerFunction();
}
catch (Throwable e) {
System.err.println("Outside:");
e.printStackTrace();
}
}
static void outerFunction() throws Throwable {
try {
innerFunction();
}
catch(Exception e) {
System.err.println("Inside:");
e.printStackTrace();
throw e.fillInStackTrace();
}
}
static void innerFunction() {
throw new RuntimeException("A custom exception");
}
}

将调用这两个不同的堆栈跟踪:

Inside:
java.lang.RuntimeException: A custom exception
at Example.innerFunction(Example.java:21)
at Example.outerFunction(Example.java:13)
at Example.main(Example.java:19)
Outside:
java.lang.RuntimeException: A custom exception
at Example.outerFunction(Example.java:13)
at Example.main(Example.java:19)

关于java - 在 log4j 中使用 fillInStackTrace() 会更便宜吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18329588/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com