2011-12-02 2 views
23

Sto esplorando l'utilizzo della memoria in Java per capire perché il mio programma perde memoria. Dopo aver rimosso il codice nel mio ciclo principale, continuo a ottenere un aumento dell'utilizzo della memoria nel tempo. Riflettendo l'utilizzo della memoria di un programma vuoto:Perché un programma Java vuoto consuma memoria?

class Nothing 
{ public static void main(String[] args) 
    { while(true); } 
} 

ho ancora visto un aumento della memoria:

Image description here

Quindi la mia domanda è: perché c'è ancora un modello di dente di sega? Perché quando gC esegue non salva tutta la memoria (ogni volta che gc gira (le valli) la memoria utilizzata aumenta di 10-20Kb (rispetto alla precedente valle))?

EDIT:

versione java "1.6.0_29"

Java (TM) SE Runtime Environment (build 1.6.0_29-b11)

Java HotSpot (TM) Cliente VM (costruire 20.4-b02, modalità mista, condivisione)

OS: Windows 7 Enterprise-32 bit

+0

Non vedo un aumento. Il ricordo sale, poi si accumula.Sembra che la memoria massima utilizzata sia costante nel tempo. –

+0

Ancora un altro strumento per cercare di trovare perdite di memoria nella tua applicazione è [Plumbr] (http://plumbr.eu). Dovrebbe essere molto più facile che lottare con i profiler e cercare di dedurre qualcosa da tutte quelle informazioni. – Nikem

risposta

10

Perché esiste ancora un modello di dente di sega?

Se non sbaglio, parte della ragione di ciò è che il monitor stesso costringe l'applicazione a creare oggetti temporanei che contengano informazioni sullo stato della raccolta dei rifiuti e sull'utilizzo della memoria.

Perché quando viene eseguito il GC fa non salva tutta la memoria (ogni volta che viene eseguito il GC (le valli) macchinari usati per la memoria aumenta di 10-20Kb (rispetto alla valle precedente))?

Credo che il monitor non veda immediatamente la quantità di memoria utilizzata dopo la raccolta dati inutili, ma, piuttosto, deve eseguire il polling frequentemente per vedere l'utilizzo della memoria. Pertanto, la "valle" percepita è necessariamente un po 'più alta della valle vera. Vorrei indovinare che l'aumento percepito nell'uso della memoria nelle valli è solo un artefatto casuale di questa discrepanza e sarebbe stato neutralizzato nel tempo. (Cioè, non penso che ci siano in realtà 10-20 KB di perdite di memoria in ogni ciclo.)

+0

Quindi, come potrei fare per ottenere un'immagine più precisa di ciò che sta accadendo sotto il cofano? – GoldfishGrenade

+0

In un programma reale o nel programma di test no-op-while-loop? In un programma reale, un dump dell'heap ti aiuterà a capire che tipo di oggetto non può essere raccolto dai rifiuti, il che può aiutarti a capire quale parte del tuo programma potrebbe essere la colpa. – ruakh

+0

+1 Questo è assolutamente causato dai bean di gestione e dal protocollo utilizzato per comunicare con loro (probabilmente RMI come impostazione predefinita). – Fredrik

4

Questo è un artefatto dal profiler, senza il profiler non ci saranno allocazioni. Diversi profiler producono diversi artefatti, a seconda di come registrano i dati. Qui di seguito si vede ciò che profiling Nothing JProfiler sarà simile:

enter image description here

Molto meno di un modello a dente di sega. Tuttavia, v'è anche un consumo di memoria minuscolo:

enter image description here

che è dovuto al fatto di creazione profili sondaggi bean java.lang.management.MemoryUsage JMX. Alla fine questo consumo attiverà anche una garbage collection.