6

I am trying to profile a Java application that uses lambdas using JProfiler. I am having trouble identifying, which lambda the profiler is showing as a hotspot:

profiler screenshot

I would appreciate any help on understanding the format of the stack trace involving lambdas like "edu.indiana.soci.spidal.vectorclass.lambda$PairwiseThread_SecDrv$23"

Thank you!

yshavit
  • 42,327
  • 7
  • 87
  • 124
Saliya Ekanayake
  • 387
  • 3
  • 10
  • 1
    You should have a call stack - work it out from there. – Boris the Spider Apr 03 '15 at 16:23
  • 2
    The lambda isn't the hotspot; the frames that say "lambda" in them are not using significant CPU, 90% of the time is going into HabaneroFactory.executeBody. – Brian Goetz Apr 03 '15 at 16:35
  • In this case, it's not a call tree view, but a hot spot view showing back traces to the hot spot at the top. The call path from HabaneroFactory.executeBody contributes 90% to the hot spot, but the hot spot is indeed the lambda. – Ingo Kegel Apr 13 '15 at 13:59

1 Answers1

3

Unfortunately, there is no direct way to identify the lambda because lambdas by nature have no name. At runtime, lambdas are currently implemented with anonymous classes. They are numbered sequentially after the $ sign with respect to the containing class.

If you turn on line number resolution in JProfiler (session settings-> profiling settings tab-> customize-> check box on the "method call recording" tab), you will see a line number on the "run" method in the hot spot back trace which should help you to find the lambda if it's the only lambda on that line.

Ingo Kegel
  • 46,523
  • 10
  • 71
  • 102
  • _"...implemented with anonymous classes..."_ They are actually [implemented](http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html) with _method handles_, to a similar effect, but more light weight. – Lii Apr 13 '15 at 14:37
  • The compiler does not emit anonymous classes. At runtime, an inner class is created whose single method is called through a method handle via indy. See `java.lang.invoke.InnerClassLambdaMetafactory`. AFAIK it is planned to change this implementation strategy in a future release. – Ingo Kegel Apr 13 '15 at 14:53
  • Sorry for making assertive statements about things I am obviously not totally sure about. It's surprisingly hard to get clear, current information about which translation strategy that is currently used. The fact that `InnerClassLambdaMetafactory` seems to be the only available `LambdaMetafactory` implementation suggests that you are right. [This presentation](http://wiki.jvmlangsummit.com/images/7/7b/Goetz-jvmls-lambda.pdf) by Brian Goetz from 2012 gives the same information. [This answer](http://stackoverflow.com/a/23991339/452775) by Holger claims method handles are used most of the time. – Lii Apr 16 '15 at 08:05
  • I remember hearing Brian Goetz say at the JavaOne 2013 that they would like to use MethodHandles but that they are still not fast enough – Ingo Kegel Apr 16 '15 at 09:01
  • @Lii: you got my answer wrong. The `invokedynamic` instruction is linked using `MethodHandle`s which in this context describe how to construct, or more generally, how to retrieve a lambda instance. And this is the topic of that answer, how these instances are *constructed*. The *target* of these handles is a runtime generated class created by the `LambdaMetafactory`. Once the `invokedynamic` instruction has been linked, it’ll work directly with that generated class. The type of the actual lambda instance will always be the generated class which is an (almost) ordinary `interface` implemenation – Holger Apr 17 '15 at 12:23
  • If `JProfiler` supports showing line numbers, it would be more useful to look at the line numbers of the lambda expression itself (the synthetic method `vectorclass.lambda$PairwiseThread_SecDrv$23`) rather than the caller as the caller is inside an entirely different class… – Holger Apr 17 '15 at 12:42
  • @Holger: Thanks for the clarification! I was actually going to ask about this in a comment on your answer, but you beat me to it here. – Lii Apr 19 '15 at 19:20