0

I'm trying to generate a Flame Graph for a Java program, using perf-map-agent. I know that you can use perf-java-record-stack to record data for a running process. I have also found out that you may use the script jmaps in the Flame Graph directory. I have found Brendan Gregg's example as well as a Stack Overflow post illustrating this. However, in none of these examples the Java process is given as an argument to perf record (which means that perf collects stack traces for the entire system).

I want to record profiling data for the whole execution of the program (and preferably nothing else). Is there any way to do this? I have tried:

perf record -a -g java -XX:+PreserveFramePointer <other JVM arguments> <my java program>; sudo ~/bin/brendangregg/FlameGraph/jmaps

which answers:

[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 1.711 MB perf.data (3449 samples) ]
Fetching maps for all java processes...
Mapping PID 2213 (user malin):
wc(1):   2970   9676 156108 /tmp/perf-2213.map

always with the same PID. This PID is a running process, not the one I tried to record data for.

Malin
  • 771
  • 1
  • 7
  • 16
  • have you tried to just omit `-a` to limit recording to the new java process? – Zulan Feb 22 '19 at 17:54
  • `-a` means 'record profile info from all cores', not 'record from all processes'. The JVM may run on more than 1 core, and my program is multi threaded as well. – Malin Feb 25 '19 at 07:40
  • That's not true, the documentation may be misleading. See also `--cpu` in the documentation. If you specify a command, `perf record` will record events on all cores of all threads from the particular process. – Zulan Feb 25 '19 at 08:06
  • And if I specify `-a`, it will record events of all processes? Anyhow, the issue is that I want to record events for the whole process, that is not attaching to a running process. If I just run perf record and thereafter generate a report of a flame graph, it won't show me the names of the Java methods. Therefore I need to use `perf-java-record-stack`or `jmaps`, but I can only find examples of how they can be used for a process that is already running. – Malin Feb 25 '19 at 08:46
  • 1
    Why not use [async-profiler](https://github.com/jvm-profiling-tools/async-profiler)? – Dan Berindei Jan 21 '20 at 18:28

1 Answers1

0

I think what you want might be:

  1. run the perf record with -a -g constantly, before the java application get fired up.
  2. run jmap while the Java application running, so that you can collect the JIT related symbols.
  3. End the perf record after the java application finished.
  4. filter the output of perf script by the pid you are interested in. At that time, your Java process is already running, and you know what pid it is. (open the output of the perf script to have a look, you will know how to filter)
  5. Run the flamegraph generation script.

In this way you can have the Java application recorded for the whole period of time.

Richard Li
  • 396
  • 1
  • 14