jmaps
jmaps
·
浏览次数 : 170
小编点评
**Summary:**
The script uses the `perf-map-agent` tool to generate symbol maps for all running `java` processes and writes them to `/tmp/perf-PID.map` files. These maps are later read by the `perf_events` command, which uses them to generate system profiles.
**Steps:**
1. **Find running `java` processes:**
- `pgrep` is used to search for all processes with the `java` suffix.
- The `pid` of each process is stored in `mapfile` names.
2. **Execute `perf-map-agent` on each process:**
- `perf-map-agent` is a tool for creating symbol maps from the `java` process's memory.
- `$AGENT_JAR` contains the Java runtime binary.
- `$AGENT_OUT` stores the path to the generated symbol map file.
3. **Remove temporary map file:**
- After `perf-map-agent` finishes, the temporary map file is deleted.
4. **Output map file information:**
- The script prints the PID, username, and size of each map file.
**Requirements:**
- `perf-map-agent` tool
- `pgrep`
- `perf_events` (optional, for reading symbol maps)
- Java runtime environment with `perf-map-agent` included
**Usage:**
1. Save the script to a file, e.g., `jmaps.sh`.
2. Make the script executable: `chmod +x jmaps.sh`.
3. Run the script: `./jmaps.sh`.
**Additional Notes:**
- `-u` option for `jmaps` allows for unfoldall analysis, including inline symbols.
- `-F 99` option for `perf record` sets the sampling frequency to 99%.
- `-a` option for `perf record` collects all available data points.
- `-g` option for `perf record` includes graphical output.
- `--sleep 30` option pauses the script execution for 30 seconds.
正文
#!/bin/bash
#
# jmaps - creates java /tmp/perf-PID.map symbol maps for all java processes.
#
# This is a helper script that finds all running "java" processes, then executes
# perf-map-agent on them all, creating symbol map files in /tmp. These map files
# are read by perf_events (aka "perf") when doing system profiles (specifically,
# the "report" and "script" subcommands).
#
# USAGE: jmaps [-u]
# -u # unfoldall: include inlined symbols
#
# My typical workflow is this:
#
# perf record -F 99 -a -g -- sleep 30; jmaps
# perf script > out.stacks
# ./stackcollapse-perf.pl out.stacks | ./flamegraph.pl --color=java --hash > out.stacks.svg
#
# The stackcollapse-perf.pl and flamegraph.pl programs come from:
# https://github.com/brendangregg/FlameGraph
#
# REQUIREMENTS:
# Tune two environment settings below.
#
# 13-Feb-2015 Brendan Gregg Created this.
# 20-Feb-2017 " " Added -u for unfoldall.
JAVA_HOME=/usr/lib/jvm/java-8-oracle
AGENT_HOME=/usr/lib/jvm/perf-map-agent # from https://github.com/jrudolph/perf-map-agent
debug=0
if [[ "$USER" != root ]]; then
echo "ERROR: not root user? exiting..."
exit
fi
if [[ ! -x $JAVA_HOME ]]; then
echo "ERROR: JAVA_HOME not set correctly; edit $0 and fix"
exit
fi
if [[ ! -x $AGENT_HOME ]]; then
echo "ERROR: AGENT_HOME not set correctly; edit $0 and fix"
exit
fi
if [[ "$1" == "-u" ]]; then
opts=unfoldall
fi
# figure out where the agent files are:
AGENT_OUT=""
AGENT_JAR=""
if [[ -e $AGENT_HOME/out/attach-main.jar ]]; then
AGENT_JAR=$AGENT_HOME/out/attach-main.jar
elif [[ -e $AGENT_HOME/attach-main.jar ]]; then
AGENT_JAR=$AGENT_HOME/attach-main.jar
fi
if [[ -e $AGENT_HOME/out/libperfmap.so ]]; then
AGENT_OUT=$AGENT_HOME/out
elif [[ -e $AGENT_HOME/libperfmap.so ]]; then
AGENT_OUT=$AGENT_HOME
fi
if [[ "$AGENT_OUT" == "" || "$AGENT_JAR" == "" ]]; then
echo "ERROR: Missing perf-map-agent files in $AGENT_HOME. Check installation."
exit
fi
# Fetch map for all "java" processes
echo "Fetching maps for all java processes..."
for pid in $(pgrep -x java); do
mapfile=/tmp/perf-$pid.map
[[ -e $mapfile ]] && rm $mapfile
cmd="cd $AGENT_OUT; $JAVA_HOME/bin/java -Xms32m -Xmx128m -cp $AGENT_JAR:$JAVA_HOME/lib/tools.jar net.virtualvoid.perf.AttachOnce $pid $opts"
(( debug )) && echo $cmd
user=$(ps ho user -p $pid)
if [[ "$user" != root ]]; then
# make $user the username if it is a UID:
if [[ "$user" == [0-9]* ]]; then user=$(awk -F: '$3 == '$user' { print $1 }' /etc/passwd); fi
cmd="sudo -u $user sh -c '$cmd'"
fi
echo "Mapping PID $pid (user $user):"
if (( debug )); then
time eval $cmd
else
eval $cmd
fi
if [[ -e "$mapfile" ]]; then
chown root $mapfile
chmod 666 $mapfile
else
echo "ERROR: $mapfile not created."
fi
echo "wc(1): $(wc $mapfile)"
echo
done
与jmaps相似的内容: