Identifying lambdas in stacktrace in Java 8
Asked Answered
E

1

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!

Eiger answered 3/4, 2015 at 16:20 Comment(3)
You should have a call stack - work it out from there.Chrysanthemum
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.Severe
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.Quipu
Q
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.

Quipu answered 13/4, 2015 at 13:56 Comment(6)
"...implemented with anonymous classes..." They are actually implemented with method handles, to a similar effect, but more light weight.Pigeonhearted
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.Quipu
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 by Brian Goetz from 2012 gives the same information. This answer by Holger claims method handles are used most of the time.Pigeonhearted
I remember hearing Brian Goetz say at the JavaOne 2013 that they would like to use MethodHandles but that they are still not fast enoughQuipu
@Lii: you got my answer wrong. The invokedynamic instruction is linked using MethodHandles 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 implemenationShotwell
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…Shotwell

© 2022 - 2024 — McMap. All rights reserved.