2012-06-11 9 views
12

Recentemente, stavo scrivendo una classe in cui ho scoperto che potevo ridurre il consumo di memoria delle istanze di ~ 10 byte/elemento, ma solo a costo di rendere il codice molto più complesso. Ciò ha aumentato le dimensioni del file compilato .class di ~ 10 KB.Come si stima il consumo totale di memoria permgen di una classe?

Suppongo che la JVM debba caricare il file .class in memoria, quindi queste modifiche non si pagherebbero da sole a meno che non fossero presenti almeno 1000 elementi. Ma questa aritmetica non funziona a meno che il 10KB extra nel file di classe sia il solo costo della maggiore complessità del codice.

suggerisce che c'è una buona quantità di memoria extra che viene consumata dalla classe nel permgen che non è solo basata sul file .class - ad esempio, sospetto che un codice più complesso possa richiedere più memoria per i metadati di ottimizzazione .

Quindi, questa domanda ha due parti:

  • Come posso misurare il consumo effettivo di memoria PermGen di una particolare classe? O in fase di esecuzione con alcuni strumenti o con strumenti di profilazione?
  • C'è un modo per stimare il consumo della memoria di permgen della classe mentre scrivo? (Con some background knowledge, è possibile stimare il consumo di memoria di istanze di classe come li sta scrivendo; mi chiedo se siamo in grado di stimare il consumo di memoria PermGen della classe stessa.)

dettagli simili per la Dalvik VM sarebbe apprezzato, ma sono principalmente concentrato su OpenJDK e sulle altre JVM "mainstream".

+0

Profiling potrebbe aiutare –

+0

requisiti di memoria dipenderà anche dal fatto HotSpot lo compila. Il codice JITed ha il suo costo. –

+0

@JesseWilson: questo è chiaramente vero, ma esiste un buon modo per stimare tale costo? È solo il consumo dell'assemblaggio grezzo, o ci sono molti libri contabili aggiuntivi? –

risposta

4

Come è possibile misurare il consumo di memoria permgen effettivo di una particolare classe? O in fase di esecuzione con alcuni strumenti o con strumenti di profilazione?

Un approccio potrebbe essere quello di caricare la classe di misurare in un classloader diversa e utilizzare jmap -permstat come presentato in questo blog entry.

Per ogni oggetto class loader, i seguenti dati sono stampati:

  1. L'indirizzo dell'oggetto classe Loader - presso l'istantanea quando è stato eseguito l'utilità.
  2. Il numero di classi caricate (definito dal caricatore con il metodo (java.lang.ClassLoader.defineClass).
  3. Il numero approssimativo di byte consumati da meta-dati per tutte le classi caricate da questa classe loader.
  4. L'indirizzo del caricatore di classe padre (se presente)
  5. Un'indicazione "live" o "dead" - indica se l'oggetto del caricatore sarà sottoposto a garbage collection in futuro.
  6. Il nome classe di questo programma di caricamento classi.
+0

Oooooh. Investirò su questo. –

+0

@LouisWasserman: hai trovato ulteriori informazioni dopo aver investigato? – dimo414

0

Questa è una risposta al tuo secondo punto; Non sono sicuro di quanto sarebbe utile, ma ho trovato che le diapositive nella presentazione Building Memory-efficient Java Applications: Practices and Challenges sono piuttosto utili per stimare la dimensione e la salute di vari oggetti Java. Si occupa di molti dettagli quando stima le dimensioni degli oggetti nelle JVM a 32 e 64 bit e fornisce anche indicazioni per rendere l'oggetto più efficiente in termini di memoria.

+0

In effetti, quella presentazione è ciò che mi ha motivato a provare a scrivere l'implementazione più complessa, ma più efficiente in termini di memoria per elemento, ma ora mi chiedo se potrei avere effettivamente ha peggiorato il problema ;) –

+0

@LouisWasserman Non necessariamente peggio, ma forse un po 'più complicato. :) –

+0

Bene ... se non ci sono mai più di 1000 elementi nelle istanze in memoria, sembrerebbe probabile che sia peggio. –

Problemi correlati