Jstat collector
| Fiche express | |
|---|---|
| Domaine | Collecte de statistiques GC des JVM en cours |
| Commande | jstat -gccause
|
| Public | processus Java du même utilisateur (ou root) |
| Voir aussi | Bash · Ps |
Script qui détecte automatiquement toutes les JVM en cours d'exécution sur une machine et lance, pour chacune, une collecte continue des statistiques de garbage collector (jstat -gccause) dans un fichier dédié — utile pour capturer l'activité GC de plusieurs applications Java sans avoir à connaître leurs PID à l'avance.
Script
#!/bin/bash
REPORT_DIR=/data/gc/report_gc_java
PS_LST=$(ps aux | grep java | grep -v grep | grep -v /bin/sh | awk '{print $2}')
V_DATE=$(date +"%Y%m%d%H%M%S")
for PID in $PS_LST; do
DEJA_TRAITE=$(grep -c "$PID" "${REPORT_DIR}/PID_TRAITES.txt")
if [ "$DEJA_TRAITE" -eq 0 ]; then
PS_NAME=$(ps aux | grep java | grep "$PID" \
| cut -d/ -f4-6 | sed -e "s/\//-/g" -e "s/://" \
| sed -e "s/batch//" -e "s/properties//" -e "s/-//g")
echo "${PID}-${PS_NAME}" >> "${REPORT_DIR}/PID_TRAITES.txt"
FILE_REPORT="${REPORT_DIR}/gccause_${PS_NAME}_${V_DATE}"
date > "$FILE_REPORT"
jstat -gccause -t "$PID" 500 >> "$FILE_REPORT" &
fi
done
Points corrigés par rapport au script d'origine :
- la commande de recherche du nom de process utilisait
rep $LINE—repn'existe pas, c'est une coquille pourgrep "$PID"(sans ça,cutrecevait la sortie complète deps aux | grep java, pas la ligne du PID visé). - les variables ne sont pas quotées dans l'original (
$LINE,$FILE_REPORT...) — risque de mauvaise interprétation si un chemin contient un espace ; corrigé ici.
Prérequis
${REPORT_DIR}doit exister avant le premier lancement.${REPORT_DIR}/PID_TRAITES.txtdoit exister (même vide) :grep -csur un fichier absent retourne une erreur et fausse le test-eq 0. À créer une fois viatouch, ou fiabiliser le script avecgrep -c "$PID" "${REPORT_DIR}/PID_TRAITES.txt" 2>/dev/null || echo 0.- le fichier
PID_TRAITES.txtn'est jamais purgé par le script : il grossit indéfiniment et un PID recyclé par le système plusieurs jours après peut être ignoré à tort (faux « déjà traité »). À vider périodiquement si la machine tourne longtemps. - chaque appel de
jstatlancé en tâche de fond n'est jamais arrêté par le script — il tourne 500 échantillons (l'intervalle par défaut dejstat -t PID 500est en millisecondes, donc environ 250 secondes) puis se termine de lui-même.
Fonctionnement de jstat -gccause
jstat -gccause -t PID INTERVALLE_MS affiche périodiquement les statistiques d'utilisation des générations mémoire de la JVM ainsi que la cause du dernier (et de l'avant-dernier) cycle de garbage collection — utile pour distinguer un GC déclenché par la pression mémoire normale d'un GC provoqué explicitement (System.gc()) ou par une allocation trop grosse. -t ajoute une colonne de timestamp relatif au démarrage de la JVM, utile pour recaler les pics dans le temps.