Sintomi

Se si verificano le seguenti condizioni, il problema potrebbe essere dovuto a sessioni non chiuse in CRX:

  • Il sistema diventa sempre più lento
  • Di tanto in tanto il sistema esaurisce la memoria (dopo poche ore, giorni o settimane, a seconda della gravità)
  • Versione più vecchia di CRX: hai molte voci di "CacheManager: resizeAll" nel file di log (il numero dietro size=... è il numero di cache; ogni sessione apre alcune cache)

Causa

Se un'applicazione apre esplicitamente CRXSessions, è responsabilità dello sviluppatore assicurare la corretta chiusura di queste sessioni. In caso contrario, tali sessioni non saranno oggetto di raccolta rifiuti e quindi rimarranno in memoria, causando i sintomi sopra elencati. Ogni CRXSession crea e mantiene il proprio set di cache che si aggiunge al consumo complessivo delle risorse.

Analisi

Al fine di individuare un problema effettivo con le sessioni non chiuse, esegui i comandi che seguono per determinare il numero complessivo delle CRXSessions attualmente conservate in memoria:

  • jmap -histo:live <pid> | grep CRXSessionImpl

La seconda colonna dell'output è il conteggio delle istanze, il che significa che molte sessioni non sono chiuse (e risiedono effettivamente in-memory). Se questo numero è significativamente superiore a 100, allora c'è un problema con CRXSessions nella tua applicazione.

Per vedere quanti oggetti CRXSession sono presenti in memoria, compresi quelli in attesa di essere raccolti, esegui il comando sottostante:

  • jmap -histo <pid> | grep CRXSessionImpl

Come per il comando precedente, la seconda colonna rappresenta il conteggio delle istanze.  Questo comunica quanti oggetti di sessione che sono in memoria siano live o non siano stati ancora raccolti.  Questo numero, confrontato con il precedente, può dirti se stai aprendo e chiudendo troppe sessioni CRX nella tua applicazione.

Se esegui CRX2.3 o CQ5.5, puoi forzare una raccolta completa di rifiuti jvm andando su http://<host>:<port>/system/console/memoryusage e cliccando sul pulsante "Esegui raccolta rifiuti".  Dopo averlo fatto, puoi eseguire nuovamente il comando di cui sopra alcune volte per vedere quanto velocemente il numero di oggetti di sessione aumenta.  Questo ti aiuterà a comprendere se la tua applicazione sta aprendo e chiudendo troppe sessioni o se hai bisogno di regolare le impostazioni del tuo gc.  Di solito, se questo è effettivamente un problema, noterai grandi pause di raccolta rifiuti jvm e prestazioni lente durante le operazioni di salvataggio nell'archivio.

Nota: L'applicazione della riga di comando jmap viene fornita con java JDK e può essere trovata nella directory del cestino nella home jdk.

Risoluzione

Per risolvere questo problema, sono necessarie ulteriori analisi per scoprire chi apre effettivamente le CRXSessions e, cosa più importante, non le chiude. A partire dalla versione 1.4.1, CRX è dotato di una modalità di debug integrata che permette di risalire al codice difettoso. Questa modalità di debug, fondamentalmente, scarica una traccia completa dello stack nel file di log standard ogni volta che una CRXSession viene aperta. Esegue anche il log di una voce ogni volta che una CRXSession viene richiusa.

Per abilitare la modalità di debug della sessione, aggiungi il seguente parametro JVM all'avvio di CRX:

  • -Dcrx.debug.sessions=true

NOTA: A seconda dell'uso del sistema, il file di log potrebbe crescere abbastanza velocemente.

Quando utilizzi l'avvio rapido, è necessario utilizzare l'opzione -nofork per assicurarsi che la proprietà del sistema sia utilizzata.

Non appena hai raccolto abbastanza stacktraces (è più facile analizzare il problema se ci sono almeno 1000 sessioni non chiuse), interrompi l'istanza e rimuovi nuovamente il parametro JVM. Il file di log (system out log o error.log a seconda della versione utilizzata) conterrà i seguenti messaggi, più le tracce di stack:

  • com.day.crx.core.CRXSessionImpl session# 193 aperta

Esegui quindi il file jar allegato con il seguente comando:

  • java -jar session_analyzer.jar <log_file> | sort > output.txt

Questo genererà un nuovo file output.txt che contiene la traccia di stack delle sessioni non chiuse, ordinate per contenuto della traccia di stack. Ogni traccia di stack è una riga e un po' "compressa" (i prefissi ripetuti vengono rimossi). L'id della sessione è alla fine della riga.

Esempio:

com.day.crx.j2ee.JCRExplorerServlet.login(JCRExplorerServlet.java:521) ResourceServlet.spoolResource(ResourceServlet.java:148) java.lang.Thread.run(Thread.java:595): session# 10023

Questo esempio significa che la sessione #10023 non è stata chiusa e la traccia di stack includeva le righe date quando la sessione è stata aperta.

Sulla base di questo output puoi trovare la posizione del codice difettoso e risolvere il problema. Nel caso in cui si verifichi un difetto nel nostro codice core del prodotto, invia una richiesta di supporto al Daycare insieme alle informazioni raccolte in precedenza.

Prodotti interessati:

CRX 1.3.x (chiedi una patch se devi analizzare il problema)
CRX 1.4.x (per la 1.4.0 è necessario installare l'hotfix nell'allegato)
CRX 2.x

Scarica

* session_analyzer_html_output.jar
Versione alternativa che ordina e raggruppa direttamente la sessione aperta con la stessa traccia di stack e la produce in una tabella html per una migliore visualizzazione, utilizzo con java -jar session_analyzer_html_output.jar &lt;stdout_logfile&gt; &gt; output.html

Questo prodotto è concesso in licenza in base alla licenza di Attribuzione-Non commerciale-Condividi allo stesso modo 3.0 Unported di Creative Commons.  I post su Twitter™ e Facebook non sono coperti dai termini di Creative Commons.

Note legali   |   Informativa sulla privacy online