【发布时间】:2016-11-05 20:03:11
【问题描述】:
我正在研究一个 aspectj 方面,它需要知道从哪里调用它。目前我正在使用
new Throwable().getStackTrace();
要访问此信息,但每个方面都需要数百微秒才能运行。
我查看了 SecurityManager 但似乎只能让我获得类名。
还有其他我错过的选择吗?
更新
我对@apangin 的回答的评论中提到了 JMH 基准测试结果:
Benchmark Mode Cnt Score Error Units
MyBenchmark.javalangaccess13i avgt 100 2025.865 ± 8.133 ns/op
MyBenchmark.javalangaccess2i avgt 100 2648.598 ± 24.369 ns/op
MyBenchmark.throwable1 avgt 100 12706.978 ± 84.651 ns/op
基准代码:
@Benchmark
public StackTraceElement[] throwable1() {
return new Throwable().getStackTrace();
}
@SuppressWarnings("restriction")
@Benchmark
public static StackTraceElement javalangaccess2i() {
Exception e = new Exception();
return sun.misc.SharedSecrets.getJavaLangAccess().getStackTraceElement(e, 2);
}
@SuppressWarnings("restriction")
@Benchmark
public static StackTraceElement javalangaccess13i() {
Exception e = new Exception();
return sun.misc.SharedSecrets.getJavaLangAccess().getStackTraceElement(e, 13);
}
在戴尔 XPS13 9343(i5-5200U @ 2.2GHz)上的 Windows 10、JDK 1.8.0_112 下运行测试
【问题讨论】:
-
显而易见的问题是你为什么需要这个。由于各种原因,获取堆栈跟踪需要相当长的时间,因此最好的办法是找到一个不涉及读取堆栈跟踪的原始问题的替代解决方案。
-
获取来电者信息很慢。例如,每个日志框架都有这个问题。他们都建议你如果需要性能,不要打开这些信息。
-
正如其他 cmets 所说:您错过的是您需要以某种方式解决的相互矛盾的要求;因为您找不到一种合理、可靠的方式来满足所有这些要求。
-
在shipilev.net/blog/2014/exceptional-performance 中包含了一些关于像这样获取堆栈跟踪的性能的详细信息 - 在这方面它可能没有“帮助”,因为它主要是说“是的,它很贵!” .但也许仍然很有趣。
-
你看过 InvocationHandler 吗?它可能不适用于您的结构,但值得一试。
标签: java performance aspectj stack-trace