Ho un'applicazione di elaborazione dati di scala che il 95% delle volte può gestire i dati lanciati in memoria. Il rimanente 5% se lasciato deselezionato di solito non colpisce OutOfMemoryError, ma entra solo in un ciclo di GC principali che picchia la CPU, impedisce l'esecuzione di thread in background e, se lo fa anche, richiede 10x-50x finché quando ha abbastanza memoria.Una metrica utile per determinare quando JVM sta per entrare in memoria/Guasto GC
Ho implementato un sistema in grado di scaricare dati su disco e trattare il flusso del disco come se fosse un iteratore in memoria. Di solito è un ordine di grandezza più lento della memoria, ma sufficiente per questi casi del 5%. Attualmente sto attivando un'euristica della dimensione massima di un contesto di raccolta che tiene traccia delle dimensioni delle varie raccolte coinvolte nell'elaborazione dei dati. Questo funziona, ma in realtà è solo una soglia empirica ad hoc.
Preferirei piuttosto che la JVM si avvicini al cattivo stato sopra riportato e si scarichi su disco in quel momento. Ho provato a guardare la memoria, ma non riesco a trovare la giusta combinazione di eden, vecchi, ecc. Per prevedere in modo affidabile la spirale della morte. Ho anche provato a controllare la frequenza dei principali GC, ma sembra anche che abbia una vasta gamma di "troppo conservatori" in "troppo tardi".
Sarebbe gradita qualsiasi risorsa per giudicare la salute di JVM e rilevare stati problematici.
Ho avuto qualcosa di simile e ho avuto dei problemi perché negli spazi di GC, * Eden * e * Survivor * sarebbe vuoto, distorcendo il vero uso della memoria e vero recupero della memoria. Attualmente sto testando la visione dei principali GC e calcolando il% libero e% recuperato in * Vecchio * e utilizzando quello per impostare una soglia. –
Alla fine, monitorare i principali GC e considerare sia la percentuale di OldGen utilizzata che la percentuale recuperata nel GC si è dimostrata il trigger più affidabile per il mio flushing su disco –
ATTENZIONE: si noti che il metodo "handleNotification" viene chiamato da un nativo codice (chiamando GarbageCollectorImpl.createGCNotification), il che significa che non è possibile eseguire il debug del codice all'interno di questo metodo. Maggiori informazioni qui: https://gist.github.com/rednaxelafx/1465445/5edcf2e1d489ba56077e27bf110090f5b4becde3 – metatechbe