I would like to do some basic profiling as simply as possible (without installing anything, if possible). I was using the Java Xprof option, as in
export JAVA_OPTS="-Xmx8192M -Xms8192M -Xprof"
That works when I invoke my program from the command line, but it does not give me any profiling data on my own program when I invoke it with sbt. Is there a simple way to get this profiling, or something similar, when running a program with sbt?
Also, incidentally, what is a good way to set the Java memory limits using JAVA_OPTS? Thanks.
Is it possible you’re being bit by the sbt forking configuration? sbt Reference Manual — Forking
If your code is running in a different process than the sbt one perhaps that would result in the profiling behavior you are seeing where the output only covers sbt itself. I think in those cases you might want to use the extra Java opts configuration for the forked run to pass the options you need through:
FWIW I’ve had great success with the Java Async Profiler lately: GitHub - jvm-profiling-tools/async-profiler: Sampling CPU and HEAP profiler for Java featuring AsyncGetCallTrace + perf_events. I found it quite easy to setup and generate flamegraphs.
Thanks for the reply. Yes, I am forking in sbt. I added
run / javaOptions += “-Xprof”
in my build.sbt file, and now I am getting profiling data on my own code. Unfortunately, it is still not very helpful. I don’t know how to interpret the results, and online searches don’t seem to help much. My program got a lot slower after some refactoring and bug fixes, and I am trying to figure out why.
I see a lot of stuff like this:
Compiled + native Method
30.5% 936 + 0 ExceptionBlob
What is this telling me?
I may try another profiling tool, but I’m not quite at that point yet.
Great, glad you got it working
Unfortunately, it is still not very helpful. I don’t know how to interpret the results
Yeah, that’s always the rub with these things. I’m afraid I can’t offer much help on interpreting prof results but I definitely share your pain that these things can often be pretty inscrutable. Flamegraphs are the only ones I’ve found to be slightly intuitive without a ton of prior study. It used to be kind of a pain to generate them for the JVM, but that async profiler has made it a lot easier
Here is what I have done a fair amount (there may be better options, but this is the best of those I tried).
(1) Use the Java async profiler, as mentioned above, to record a
(2) Open this in Java Mission Control (
jmc from the command line).
(3) Trace the code and find where most time was being taken.
In many cases this showed what needed to be optimized (e.g. by memoizing).