2012-01-08 8 views

risposta

17

Ogni JVM è diverso, ma la JVM HotSpot NON basano principalmente sul conteggio di riferimento come mezzo per la raccolta dei rifiuti.Il conteggio dei riferimenti ha il vantaggio di essere semplice da implementare, ma è intrinsecamente soggetto a errori. In particolare, se si dispone di un ciclo di riferimento (un insieme di oggetti che si riferiscono tutti l'un l'altro in un ciclo), il conteggio dei riferimenti non recupererà correttamente tali oggetti perché hanno tutti un conteggio di riferimento diverso da zero. Questo ti costringe a utilizzare un garbage collector ausiliario di volta in volta, che tende ad essere più lento (Mozilla Firefox ha questo problema esatto e la loro soluzione era quella di aggiungere un garbage collector al costo di una buona leggibilità del codice). Questo è il motivo per cui, ad esempio, linguaggi come il C++ tendono ad avere una combinazione di shared_ptr s che usa il conteggio dei riferimenti e weak_ptr s che non usano cicli di riferimento.

Inoltre, associare un conteggio di riferimento a ciascun oggetto comporta il costo di assegnazione di un riferimento superiore al normale, a causa della contabilità aggiuntiva necessaria per la regolazione del conteggio dei riferimenti (che peggiora solo in presenza di multithreading). Inoltre, l'utilizzo del conteggio dei riferimenti preclude l'utilizzo di alcuni tipi di allocatori di memoria veloci, il che può essere un problema. Inoltre, tende a portare alla frammentazione dell'heap nella sua forma ingenua, dal momento che gli oggetti sono disseminati attraverso la memoria piuttosto che con tempi di allocazione ridotti, che causano una scarsa localizzazione.

HotSpot JVM utilizza una varietà di tecniche diverse per eseguire la garbage collection, ma il garbage collector primario è denominato collettore stop-and-copy. Questo collector funziona allocando gli oggetti in modo contiguo nella memoria l'uno accanto all'altro e consente un'allocazione estremamente veloce (una o due istruzioni di assemblaggio) di nuovi oggetti. Quando lo spazio si esaurisce, tutti i nuovi oggetti vengono sottoposti a GC simultaneamente, il che di solito elimina la maggior parte dei nuovi oggetti che sono stati costruiti. Di conseguenza, il GC è molto più veloce di un'implementazione di conteggio di riferimento tipica e finisce per avere una località migliore e prestazioni migliori.

Per un confronto di tecniche di raccolta dei rifiuti, insieme a una rapida panoramica di come il GC in HotSpot funziona, si consiglia di controllare these lecture slides da un corso compilatori che ho insegnato la scorsa estate. Si consiglia inoltre di guardare the HotSpot garbage collection white paper che fornisce maggiori dettagli su come funziona il garbage collector, compresi i metodi di ottimizzazione del collector su un'applicazione per applicazione.

Spero che questo aiuti!

+0

+1 Vale anche la pena ricordare che i counter counter atomici per i programmi multithread sono ancora più costosi. –

+1

Una discussione di questo è incompleta senza menzionare la pausa GC. –

2

Perché non funziona in modo strettamente basato sul conteggio dei riferimenti.

Considerare riferimenti circolari che non sono più raggiungibili dalla "radice" dell'applicazione.

Ad esempio:

APP ha un riferimento SOME_SCREEN

SOME_SCREEN ha un riferimento SOME_CHILD

SOME_CHILD ha un riferimento SOME_SCREEN

ora, APP gocce è riferimento SOME_SCREEN.

In questo caso, SOME_SCREEN ha ancora un riferimento a SOME_CHILD, e SOME_CHILD ha ancora un riferimento alla SOME_SCREEN - quindi, in questo caso, il tuo esempio non funziona.

Ora, altri (Apple con ARC, Microsoft con COM, molti altri) hanno soluzioni per questo e funzionano in modo più simile al modo in cui lo descrivete.

Con ARC è necessario annotare i propri riferimenti con parole chiave come strong e weak per consentire a ARC di sapere come gestire questi riferimenti (ed evitare riferimenti circolari) ... (non leggere troppo nel mio specifico esempio con ARC poiché ARC gestisce queste cose in anticipo durante il processo di compilazione e non richiede uno specifico runtime per sé), quindi può sicuramente essere fatto in modo simile a come lo descrivi, ma non è fattibile con alcune delle funzionalità di Giava. Credo inoltre che la COM funzioni in modo più simile a come la descrivi ... ma, ancora una volta, ciò non è privo di una certa considerazione da parte dello sviluppatore.

In realtà, nessun sistema di conteggio di riferimento "semplice" potrebbe mai essere praticabile senza una certa quantità di pensiero dallo sviluppatore dell'applicazione (per evitare i riferimenti circolari, ecc)

0

perché il garbage collector in JVM moderna è nessun inseguimento più numero di referenze. Questo algoritmo viene utilizzato per insegnare come funziona GC, ma era sia dispendioso in termini di risorse che incline agli errori (ad esempio, dipendenze cicliche).

+0

non credo che qualsiasi JVM corrente principale mai utilizzato il conteggio di riferimento. –

2

conteggio di riferimento presenta le seguenti limitazioni:

  • È MOLTO male per multithreading prestazioni (sostanzialmente, ogni assegnazione di un riferimento oggetto deve essere protetto).
  • Non è possibile cicli liberi automaticamente
Problemi correlati