Java garbage collection

Java automaticamente le chiamate garbage collector, quindi perché abbiamo bisogno di chiamate manuali per la raccolta dei rifiuti? Quando si deve usare Sistema.(gc)

InformationsquelleAutor Nageswaran | 2011-02-23



7 Replies
  1. 43

    Java automaticamente le chiamate garbage collector, quindi perché abbiamo bisogno di chiamate manuali per la raccolta dei rifiuti?

    Non abbiamo bisogno di loro. Infatti, nella maggior parte dei casi la chiamata System.gc() è dannoso per le prestazioni dell’applicazione. Vedi la mia risposta a “Perché è una buona pratica per sistema di chiamata di gc” per una spiegazione dettagliata.

    Quando si deve usare il Sistema.(gc)

    Se l’applicazione sa che sta andando in una fase in cui si ha niente altro da fare E l’utente è improbabile che l’avviso di una procedura di garbage collection, allora forse è OK chiamata a System.gc() nel tentativo di fermare l’utente che ha riscontrato GC pause in futuro.

    I lati negativi sono:

    • Chiamata System.gc() in genere si innesca un completo GC che richiede molto più di un GC del “nuovo spazio”.
    • L’utente può in realtà la cura /preavviso. Per esempio, se si chiama System.gc() tra “livelli” in un gioco, fare il caricamento del livello successivo richiedere più tempo.
    • Costringendo il GC, che stanno causando la JVM di utilizzare cicli di CPU in più, ecc, che possono potenzialmente interferire con altri cose che l’utente sta facendo la sua macchina.

    (Ci possono essere anche motivi legittimi al call System.gc() nel test di unità, e durante il debug del sistema.)

    • +1 per indicare l’effetto sulle prestazioni dell’applicazione.
  2. 16

    Non c’e ‘ bisogno di chiamare per la raccolta dei rifiuti in modo esplicito e chiamando System.gc() è solo un suggerimento, la JVM può ignorare il tuo suggerimento.

    L’unico uso pratico che posso pensare è

    1. Durante il debug, costringendo una collezione in grado di esporre una perdita di memoria
    2. Se il programma passa attraverso prevedibile cicli intensi di calcolo seguita da nessun calcolo (come un gioco a turni), durante il no-periodo di calcolo della CPU potrebbe essere utilizzato per una proposta di garbage collection per evitare che il jitter durante l’intenso calcolo porzioni.
    • +1 per indicare la perdita di memoria di utilizzo.
    • in realtà, non vedo come si esegue il GC potrebbe “esporre” una perdita di memoria. Si spiega?
    • Quando guardando il mucchio di un’applicazione, in genere si aspetta un dente di sega look in cui heap size restituisce all’incirca la stessa dimensione dopo ogni GC. Le applicazioni che mantengono per la quantità di dati (una sorta di perdita di memoria) tendono a continuare a crescere heap.
    • Vedo di cosa si sta ottenendo. Ma è possibile ottenere lo stesso effetto utilizzando una memory profiler … di hacking senza l’applicazione per chiamare il GC.
    • Sì, sono d’accordo. Volevo dire un debugger, non nel codice dell’applicazione e vedo che è un po ‘ di tangenziale per Sistema di chiamata.gc() in modo esplicito.
  3. 4

    Sistema.(gc) è solo un suggerimento. Ma ha senso in alcune situazioni.

    Si supponga di avere classe MyClass, e ti stai chiedendo quanta memoria ha un esempio prendere. Cosa si può fare è questo (grosso modo):

    MyClass [] objects= new MyClass[100000];
    System.gc();
    long memoryNow = Runtime.getRuntime().freeMemory();
    for (int i = 0; i < 100000; i ++) {
      objects[i] = new MyClass();
    }
    System.gc();
    long memoryLater = Runtime.getRuntime().freeMemory();
    int objectSize = (int)((memoryLater - memoryNow) / 100000);

    Ci sono altri casi simili ho trovato il Sistema.gc() per essere utile.

  4. 1

    Un aspetto non ancora menzionato è che alcuni tipi di oggetti possono chiedere entità al di fuori di se stessi, di fare le cose sul loro conto (ad esempio, dare loro l’accesso esclusivo a un non fungibili risorsa come un file), a scapito di altri enti. Quando un garbage collection è eseguita, il sistema non solo di liberare la memoria che è stato precedentemente occupato da oggetti non raggiungibili, ma sarà anche chiamata finalize su oggetti che gli avvisi sono stati abbandonati, permettendo ad oggetti di notificare al di fuori entità che i loro servizi non sono più necessari. E ‘ del tutto possibile per un programma, per raggiungere uno stato in cui c’è un sacco di memoria, ma una risorsa necessaria è disponibile a causa di un oggetto è stato concesso l’accesso esclusivo e da allora è stato abbandonato senza rilascio. Costringendo il garbage collector per l’esecuzione in tale situazione, a volte, di liberare le risorse necessarie.

    • Che è vero. Tuttavia, il fatto che necessario per fare questo significa che l’applicazione sta facendo un cattivo lavoro di gestire le risorse. Un libro ben scritto applicazione utilizzerà finally blocchi (o simili) per garantire che le risorse non perdere”.
    • Mentre è vero che ben scritte le applicazioni devono deterministicamente pulire le risorse, garantire che le cose sarebbero puliti, in caso di eccezioni è stato imbarazzante fino a Java 7. Anche in Java 7, alcuni casi sono ancora troppo difficili da gestire in modo pulito (soprattutto nei casi in cui i costruttori di generare eccezioni).
    • Puoi spiegare il problema con i costruttori in Java 7? Stai parlando di bug nella classifica costruttori stessi, o qualcos’altro.
    • Ci sono almeno due casi problematici con i costruttori: (1) se la costruzione di un derivato-oggetto di classe richiede l’acquisizione di una risorsa e passando per la base-costruttore della classe, è difficile evitare perdite di risorsa se il costruttore di base getta, dato che Java non permette a base chiamata al costruttore per essere avvolto in un try/finally blocco [anche se la JVM sarebbe]; (2) se la base-costruttore della classe acquisisce una risorsa e una derivata-funzione di costruzione della classe getta, la risorsa avrà una perdita, a meno che il tiro si è verificato all’interno di un blocco try/finally. Nota che…
    • …una dichiarazione di campo come myThing = new Thing(); non può essere avvolto in un try-finally, quindi, se tale dichiarazione getta, se non si acquisisce risorse, base-classe delle perdite di risorse, sarà difficile evitare poiché nessun riferimento alla base-oggetto di classe esistenti. L’unico modo che conosco per evitare perdite di risorse in questi casi è usare ThreadLocal per tenere traccia delle risorse che sono state acquisite, ma non è ancora stato “consegnato” ai soggetti che hanno promesso di chiudere.
    • Re 1) Un modo per evitare il problema è quello di nascondere la sottoclasse costruttore, e di esporre un metodo factory, invece. Quindi il metodo factory passare la risorsa sottoclasse costruttore come un parametro supplementare. Il metodo factory quindi possibile chiudere la risorsa, se il costruttore non terminate normalmente. Re 2) penso che lo stesso approccio funziona. Il punto è che il problema può essere trattati alla fonte.
    • Utilizzando un metodo factory per attaccare problema #1 funziona, ma è utilizzabile solo se non c’è bisogno di costruire sottoclasse istanze di utilizzo della risorsa. Per la fabbrica di eseguire le operazioni di pulizia necessarie nello scenario #2, deve in qualche modo avere una copia dell’oggetto in fase di costruzione. Si potrebbe, ad esempio, hanno la fabbrica di passare un AutoCloseable[1] array al costruttore, e hanno il costruttore di base archivio di this c’è, ma che comporta una posizione troppo stretto collegamento tra la base e classi derivate, e non c’è la convenzione standard per farlo.
    • “ma è utilizzabile solo se non c’è bisogno di costruire sottoclasse istanze di utilizzo della risorsa.” non ho capito il tuo punto. Qualsiasi posto si scrive new Subclass(...) si può sostituire con una chiamata a un metodo factory.
    • Mi sbagliavo sul caso #2. La soluzione c’è per la sottoclasse costruttore per avvolgere il codice in cui viene generata l’eccezione in un try/finally … e chiamare il close() metodo della superclasse, sulla via d’uscita.
    • Che funziona, a condizione che l’eccezione viene lanciata in un luogo che può essere avvolto con try/finally. Se l’eccezione viene generata da qualcosa di simile a un campo di dichiarazione Thing thingie = new Thing(this, that, theOther); non c’è modo di avvolgere in un try/finally.

  5. 1

    Il garbage collector è sempre chiamato dalla JVM quando non c’è abbastanza memoria per allocare nuovi oggetti nell’heap. Durante la chiamata il garbage collector, segue l’Fermare il Mondo norme e per questo si chiama il System.gc() metodo.

    Anche ricordare che la JVM anche corre parallela gc thread per rimuovere gli oggetti non utilizzati dalla memoria . Quindi tutto e ogni minuto JVM mantiene memoria heap e cerca sempre di non sovraccaricare esso. Quindi non c’è alcun obbligo di chiamare in modo esplicito System.gc() o Runtime.gc() metodo.

    Se volete maggiori dettagli su questo si può ottenere qui per le informazioni pertinenti.

  6. 0

    Processo di Garbage collection non è sotto il controllo dell’utente.Quindi non ha senso chiamare System.gc(); in modo esplicito. Si interamente dipende dalla JVM.

    Qualche giorno fa, mi aveva chiesto esattamente la stessa domanda : [Qui].

    Infatti, a molte domande relative alla chiamata di System.gc(); esplicitamente già chiesto e ha risposto qui. Chiamata System.gc(); esplicitamente è sempre considerato come poveri l’abilità di programmazione, anche se non fa alcun male.

    Qui ci sono pochi link che si dovrebbe passare attraverso di essa. Sarà sicuramente chiarire il tuo dubbio.

    PS : Btw, si dovrebbe seriamente prendere
    il extra sforzo per passare attraverso
    simile StackOverflow domande prima di postare sui tuoi dubbi.

    • “… anche se non fa alcun male” – e ‘ in genere di rendere l’applicazione andare più lento, e che conta come un “danno”.
  7. 0

    Non c’è bisogno di chiamare System.gc() o Runtime.getRuntime().gc(). La JVM internamente controlli di garbage collection se si trova che è a corto di memoria.

Lascia un commento