OutOfMemoryError: limite di overhead GC superato

1. Panoramica

In poche parole, la JVM si occupa di liberare memoria quando gli oggetti non vengono più utilizzati; questo processo è chiamato Garbage Collection (GC).

L' errore GC Overhead Limit Exceeded appartiene alla famiglia di java.lang.OutOfMemoryError ed è un'indicazione di esaurimento delle risorse (memoria).

In questo breve articolo, vedremo cosa causa l' errore java.lang.OutOfMemoryError: GC Overhead Limit Exceeded e come può essere risolto.

2. Errore limite overhead GC superato

OutOfMemoryError è una sottoclasse di java.lang.VirtualMachineError ; viene lanciato dalla JVM quando incontra un problema relativo all'utilizzo delle risorse. Più specificamente, l'errore si verifica quando la JVM ha impiegato troppo tempo per eseguire Garbage Collection ed è stata in grado di recuperare solo pochissimo spazio nell'heap.

Secondo i documenti Java, per impostazione predefinita, la JVM è configurata per generare questo errore se il processo Java impiega più del 98% del suo tempo a eseguire GC e quando solo meno del 2% dell'heap viene ripristinato in ogni esecuzione. In altre parole, ciò significa che la nostra applicazione ha esaurito quasi tutta la memoria disponibile e Garbage Collector ha impiegato troppo tempo a tentare di ripulirlo e ha fallito ripetutamente.

In questa situazione, gli utenti riscontrano un'estrema lentezza dell'applicazione. Alcune operazioni, che di solito vengono completate in millisecondi, richiedono più tempo per essere completate. Questo perché la CPU sta utilizzando l'intera capacità di Garbage Collection e quindi non può eseguire altre attività.

3. Errore in azione

Diamo un'occhiata a un pezzo di codice che lancia java.lang.OutOfMemoryError: GC Overhead Limit Exceeded.

Possiamo ottenere ciò, ad esempio, aggiungendo coppie chiave-valore in un ciclo non terminato:

public class OutOfMemoryGCLimitExceed { public static void addRandomDataToMap() { Map dataMap = new HashMap(); Random r = new Random(); while (true) { dataMap.put(r.nextInt(), String.valueOf(r.nextInt())); } } }

Quando viene richiamato questo metodo, con gli argomenti JVM come -Xmx100m -XX: + UseParallelGC (la dimensione dell'heap Java è impostata su 100 MB e l'algoritmo GC è ParallelGC), otteniamo un errore java.lang.OutOfMemoryError: GC Overhead Limit Exceeded . Per ottenere una migliore comprensione dei diversi algoritmi di Garbage Collection, possiamo controllare il tutorial Java Garbage Collection Basics di Oracle.

Otterremo un errore java.lang.OutOfMemoryError: GC Overhead Limit Exceeded molto rapidamente eseguendo il seguente comando dalla radice del progetto:

mvn exec:exec

Va inoltre notato che in alcune situazioni è possibile che si verifichi un errore di spazio nell'heap prima di riscontrare l'errore GC Overhead Limit Exceeded .

4. Risoluzione dell'errore di superamento del limite di overhead GC

La soluzione ideale è trovare il problema sottostante con l'applicazione esaminando il codice per eventuali perdite di memoria.

È necessario rispondere alle seguenti domande:

  • Quali sono gli oggetti nell'applicazione che occupano ampie porzioni dell'heap?
  • In quali parti del codice sorgente vengono allocati questi oggetti?

Possiamo anche utilizzare strumenti grafici automatizzati come JConsole che aiuta a rilevare problemi di prestazioni nel codice, incluso java.lang.OutOfMemoryErrors.

L'ultima risorsa sarebbe aumentare la dimensione dell'heap alterando la configurazione di avvio della JVM. Ad esempio, questo fornisce 1 GB di spazio heap per l'applicazione Java:

java -Xmx1024m com.xyz.TheClassName

Tuttavia, questo non risolverà il problema se ci sono perdite di memoria nel codice dell'applicazione effettiva. Invece, rimanderemo semplicemente l'errore. Pertanto, è più consigliabile rivalutare accuratamente l'utilizzo della memoria dell'applicazione.

5. conclusione

In questo tutorial, abbiamo esaminato java.lang.OutOfMemoryError: GC Overhead Limit Exceeded e le ragioni alla base.

Come sempre, il codice sorgente relativo a questo articolo può essere trovato su GitHub.