2009-09-18 2 views
11

Ho questa applicazione web che richiede un po 'di ottimizzazione della memoria. Mentre sto già profilando l'applicazione stessa e tagliando le cose, la JVM stessa sembra eccessivamente gonfia per me nella nostra istanza più attiva. (Le istanze di volume più bassi non hanno questo problema.) I dettagli:Che impatto ha l'opzione -d64 sull'uso della memoria residente di Sun JVM?

  • Piattaforma:
    • RHEL4 a 64-bit (Linux 2.6.9-78.0.5.ELsmp #1 SMP x86_64)
    • Sun Java 6 (Java HotSpot(TM) 64-Bit Server VM (build 10.0-b23, mixed mode))
    • Tomcat 6 con
  • La mia webapp ha attualmente un codice che in produzione richiede i vantaggi di in esecuzione a 64 bit.
  • Ho notato che dopo un po 'di tempo (una settimana) la dimensione della memoria residente della JVM (come mostrato in alto) è tre volte la dimensione della mia impostazione -Xmx.
  • La dimensione della memoria non-mucchio, ecc sono tutte relativamente banali, una semplice percentuale singola cifra della dimensione heap
  • C'è solo una sezione di codice che richiede uno spazio di indirizzamento bit 64 bit

Se potessi rifattorizzare la necessità di una JVM a 64 bit e rilasciare lo switch -d64, ciò renderebbe più piccolo l'ingombro di memoria residente della JVM? In altre parole ...

Qual è l'impatto, se presente, dell'interruttore -d64 sull'utilizzo della memoria residente di Sun JVM?

risposta

18

L'utilizzo dell'interruttore d64 porta la JVM nella modalità a 64 bit. Tecnicamente, su Solaris/Linux e molti Unix, il processo JVM verrà eseguito nel modello LP64.

Il LP64 model è diverso dal modello a 32 bit (ILP32) in quanto i puntatori sono larghi 64 bit anziché puntatori a 32 bit. Per la JVM, ciò consente una maggiore indirizzabilità della memoria, ma significa anche che la dimensione occupata dai soli riferimenti all'oggetto è raddoppiata. Quindi c'è una maggiore quantità di spazio per lo stesso numero di oggetti in un dato momento in una JVM a 32 bit e in una a 64 bit.

Un'altra cosa che viene spesso dimenticata è la dimensione delle istruzioni stesse. Su una JVM a 64 bit, la dimensione delle istruzioni occuperà le dimensioni del registro macchina nativo.

Se tuttavia si utilizza compressed object pointers in un ambiente a 64 bit, la JVM codificherà e decodificherà i puntatori quando possibile per dimensioni di heap superiori a 4 GB. In breve, quando si usano i puntatori compressi, la JVM tenta di utilizzare il più possibile i valori a 32 bit.

Suggerimento: attivare il flag UseCompressedOops, utilizzando -XX: + UseCompressedOops per sbarazzarsi di alcuni dei rigonfiamenti. YMMV, ma people have reported upto 50% drop in memory bloat by using compressed oops.

EDIT

The UseCompressedOops flag is supported in version 14.0 of the Java HotSpot VM, available from Java 6 Update 14 onwards.

+0

Risposta fantastica. Mi hai convinto a rifattorizzare il mio codice e rilasciare il -d64. Tornerò e commenterò come va.Lavorerò anche su un aggiornamento JVM, quindi posso provare -XX: + UseCompressedOops. Grazie. Hai vinto il premio * Stu's World Famous "Awesome Coder of the Month" * per settembre 2009! –

+0

Wow, non ho mai saputo che google-fu avrebbe chiarito una simile reazione. Grazie, sono stupito dalla tua risposta! A proposito, se riesci a mantenere il tuo heap a meno di 4 GB, la tua JVM a 64 bit si comporterà come una a 32 bit; non sono sicuro di alcun impatto sulle prestazioni. –

+0

Più di Google-fo !!! Mi ero guardato intorno e stavo pensando che sarebbe valsa la pena ... ma ci sono * soooo * molti switch JVM, valori e if-then-but cases e gotchyas. Può essere opprimente, e il mio bisogno era di "* farlo" */* "non disturbare" * risposta, accompagnata da un cucchiaio di alimentazione pertinente. Grazie ancora. –