Jstat collector

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
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 $LINErep n'existe pas, c'est une coquille pour grep "$PID" (sans ça, cut recevait la sortie complète de ps 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.txt doit exister (même vide) : grep -c sur un fichier absent retourne une erreur et fausse le test -eq 0. À créer une fois via touch, ou fiabiliser le script avec grep -c "$PID" "${REPORT_DIR}/PID_TRAITES.txt" 2>/dev/null || echo 0.
  • le fichier PID_TRAITES.txt n'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 jstat lancé en tâche de fond n'est jamais arrêté par le script — il tourne 500 échantillons (l'intervalle par défaut de jstat -t PID 500 est 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.

Voir aussi

  • Ps — lister et filtrer les processus
  • Bash — boucles for, substitution de commandes