【问题标题】:Identifying lambdas in stacktrace in Java 8在 Java 8 的堆栈跟踪中识别 lambda
【发布时间】:2015-04-03 16:20:26
【问题描述】:

我正在尝试使用 JProfiler 分析使用 lambdas 的 Java 应用程序。我无法识别分析器显示为热点的 lambda:

对于理解涉及 lambda 的堆栈跟踪格式(如“edu.indiana.soci.spidal.vectorclass.lambda$PairwiseThread_SecDrv$23”)的任何帮助,我将不胜感激

谢谢!

【问题讨论】:

  • 你应该有一个调用堆栈 - 从那里开始工作。
  • lambda 不是热点;其中显示“lambda”的帧没有使用大量 CPU,90% 的时间都进入 HabaneroFactory.executeBody。
  • 在这种情况下,它不是调用树视图,而是显示回溯到顶部热点的热点视图。 HabaneroFactory.executeBody 的调用路径对热点贡献了 90%,但热点确实是 lambda。

标签: java lambda java-8 jprofiler


【解决方案1】:

不幸的是,没有直接的方法来识别 lambda,因为 lambda 本质上没有名称。在运行时,lambdas 当前是使用匿名类实现的。相对于包含的类,它们在 $ 符号之后按顺序编号。

如果你在JProfiler中开启了行号解析(会话设置->分析设置选项卡->自定义->“方法调用记录”选项卡上的复选框),你会在“运行”方法中看到一个行号如果它是该行上唯一的 lambda,则热点回溯应该可以帮助您找到 lambda。

【讨论】:

  • "...用匿名类实现..." 它们实际上是带有方法句柄implemented,效果类似,但是重量更轻。
  • 编译器不会发出匿名类。在运行时,会创建一个内部类,其单个方法通过 indy 的方法句柄调用。见java.lang.invoke.InnerClassLambdaMetafactory。 AFAIK 计划在未来的版本中更改此实施策略。
  • 很抱歉,我对我显然不完全确定的事情做出了自信的陈述。很难获得关于当前使用哪种翻译策略的清晰、最新信息。 InnerClassLambdaMetafactory 似乎是唯一可用的 LambdaMetafactory 实现这一事实表明您是对的。 This presentation 来自 2012 年的 Brian Goetz 提供了相同的信息。 Holger 的This answer 声称大部分时间都使用方法句柄。
  • 我记得在 JavaOne 2013 上听到 Brian Goetz 说他们想使用 MethodHandles,但仍然不够快
  • @Lii:你的回答错了。 invokedynamic 指令是使用 MethodHandles 链接的,在这种情况下,它描述了如何构造,或者更一般地说,如何检索 lambda 实例。这就是那个答案的主题,这些实例是如何构造的。这些句柄的目标 是由LambdaMetafactory 创建的运行时生成的类。一旦invokedynamic 指令被链接,它将直接与生成的类一起工作。实际 lambda 实例的类型将始终是生成的类,它是(几乎)普通的 interface 实现
猜你喜欢
  • 1970-01-01
  • 2015-10-19
  • 2019-05-29
  • 1970-01-01
  • 2018-02-15
  • 2019-10-02
  • 1970-01-01
  • 2011-11-20
  • 2014-05-15
相关资源
最近更新 更多