2012-09-06 3 views
15

Se l'heap è pieno, la JVM genera uno OutOfMemoryError. Ma è certo che una raccolta di dati (completa) avviene sempre prima che venga lanciata un'eccezione?Il garbage collector è garantito per l'esecuzione prima dell'errore di memoria insufficiente?

Ciò significherebbe che la memoria è piena solo con oggetti di riferimento forti (o raggiungibili da GC Roots) quando viene generata l'eccezione.

Modifica: presuppone che Sun JVM - HotSpot sia in discussione.

+1

In java, è un "Errore di memoria insufficiente" – arshajii

+0

@A. R. S .: In realtà ho notato questo quando ho visto il commento del tag 'outofmemoryexception', che fa riferimento a .NET. Ho curato, grazie per l'avviso. – m3th0dman

+0

Sono curioso di sapere perché stai facendo esattamente questa domanda (per non dire che non era ragionevole, ma per sapere quali considerazioni stai facendo) – chiccodoro

risposta

19

Il Java Machine Specification states in section 6.3 (sottolineatura mia):

OutOfMemoryError: Java virtual l'implementazione della macchina ha esaurito memoria virtuale o fisica, e il gestore di archiviazione automatico non è riuscito a a recuperare memoria sufficiente per soddisfare una richiesta di creazione dell'oggetto.

Quindi la JVM garantisce che proverà tutto ciò che è in suo potere per liberare memoria attraverso la garbage collection prima di lanciare un OOME.

2

Non è garantito che l'ultima operazione precedente lo OutOfMemoryError sia la garbage collection. Molto probabilmente no, dal momento che la raccolta dei rifiuti ridurrebbe la quantità di memoria utilizzata non aumentandola.

+0

In questo caso, esiste la possibilità che da un heap da 2 GB, forse 0,5 GB sia costituito da oggetti non raggiungibili e che l'OutOfMemoryError venga generato anche se, dal mio POV (del programmatore), 1/4 dell'heap è gratuito. Potresti suggerire qualche riferimento per questo? – m3th0dman

+0

* "Probabilmente no, dato che la garbage collection ridurrebbe la quantità di memoria utilizzata non aumentandola" * a meno che non ci sia memoria da recuperare ... Diverse risposte su SO sembrano dire il contrario (cioè che la JVM proverà a liberare risorse con un GC prima di lanciare un OOE). – assylias

12

Il raccoglitore di garage verrà eseguito di solito prima che venga emesso un errore OutOfMemoryError. Tuttavia si potrebbe ottenere un OOME senza un GC se

  • tenta di creare un oggetto molto grande (ad esempio, più grande della heap)
  • avviare un thread e non c'è abbastanza memoria virtuale o le risorse per avviare il thread .
  • versioni precedenti di Java generano questo errore se si raggiunge la massima memoria diretta.
7

Non ha la garanzia che una garbage collection completa è stata eseguita, ma che la VM ha cercato di rendere abbastanza memoria disponibile attraverso la raccolta dei rifiuti. Si potrebbe avere scoperto che nel API documentation for the OutOfMemoryError class:

generata quando la Java Virtual Machine non può assegnare un oggetto perché è fuori della memoria, e non più di memoria potrebbe essere messa a disposizione dal garbage collector.

Si noti che ci sono casi in cui il garbage collector può decidere che la memoria sufficiente non è disponibile senza in realtà cercando di eliminare istanze di oggetti non referenziati. L'esempio più ovvio è se si tenta di allocare più memoria in una volta (ad esempio un array di byte di grandi dimensioni) rispetto alla dimensione massima dell'heap. In questo caso, un OutOfMemoryError può essere lanciato senza che il garbage collector venga eseguito.

2

Ci sono altri fattori aggiuntivi da considerare oltre a ciò che le persone hanno già risposto, ad esempio la politica di garbage collection che si sta utilizzando. Considera la garbage collection della velocità effettiva, che genererà un'eccezione di memoria esaurita se si impiegano troppo tempo per la raccolta e non viene liberata abbastanza memoria (anche se le modifiche recenti potrebbero aver cambiato le cose). Detto tutto questo non avrebbe assunto la raccolta dei rifiuti avviene in qualsiasi momento entro l'esecuzione di un'applicazione che sto scrivendo ...