2009-07-08 13 views
59

Dopo la lettura già chiesto domanda sul tema e un sacco di googling io non sono ancora in grado di avere una visione chiara di -Xms opzioneJVM parametri heap

La mia domanda è: qual è la differenza tra il java -Xms=512m -Xmx=512m e java -Xms=64m -Xmx=512m ?

Per ora ho la seguente risposta:

L'unica differenza è nel numero di garbage collection che verranno eseguiti durante la corsa di mia applicazione e il numero di allocazioni di memoria. Ho ragione ?

Ecco le mie ragioni per questa risposta:

impostando l'opzione -Xms a 512m non si traduca nella mia applicazione utilizza davvero 512M di memoria fisica dopo l'avvio. Immagino che questo sia legato alla moderna gestione della memoria virtuale del SO e alle allocazioni di pagine pigre. (Ho notato che l'impostazione -Xms a 512M o 64M non cambia affatto la memoria utilizzata iniziale riferito sia dai vertici su Linux o con il task manager in Windows)

qualcuno può aiutarmi a capire l'impatto di questa Xms opzione o indicarmi i collegamenti che mi aiuteranno a capirlo?

Grazie in anticipo

Manu

risposta

31

Per riepilogare le informazioni trovate dopo il collegamento: La JVM alloca l'importo specificato da -Xms ma il sistema operativo in genere non assegna le pagine reali finché non sono necessarie. Quindi la JVM alloca la memoria virtuale come specificato da Xms, ma assegna solo la memoria fisica necessaria.

È possibile visualizzare questo utilizzando Process Explorer di Sysinternals invece di Task Manager su Windows.

Quindi c'è una vera differenza tra l'utilizzo di -Xms64M e -Xms512M. Ma penso che la differenza più importante sia quella che hai già indicato: il garbage collector funzionerà più spesso se hai davvero bisogno dei 512 MB, ma solo 64MB.

+12

Penso che la sintassi reale sia -Xms64m e non -Xms = 64m. Se mi sbaglio, per favore, torna indietro! – Burkhard

+1

È venuto fuori durante la ricerca di alcuni dei punti migliori di jvm config. La risposta accettata qui è molto diversa dalla mia comprensione di questi valori. Sì, la maggior parte del SO renderà disponibili solo le pagine fisiche quando viene rilevato un errore di pagina minore mentre l'app tenta di accedere alla memoria che ha malloc'ed - ma Xms specifica la quantità iniziale di memoria malloced da jvm - che pone un limite superiore sul numero di pagine che possono essere assegnate * senza * l'app mallocà più memoria - e nel caso di Java, sarà solo malloc più memoria (fino a Xmx) se memoria insufficiente è resa disponibile da gc – symcbean

+0

@symcbean Sono confuso . Sembra che la tua comprensione non sia molto diversa da quella che è nella risposta. Stai solo usando parole diverse, ma stai descrivendo esattamente lo stesso comportamento. – Turismo

4

se hai scritto: -Xms512m -Xmx512m quando si inizia, Java allocare in quelli momento 512m di RAM per il suo processo e l'incremento Cant.

-Xms64m -Xmx512m all'avvio, java assegna solo 64 m di ram per il suo processo, ma java può incrementare la sua occupazione di memoria per 512 m.

Penso che la seconda cosa è meglio perché si dà a java la gestione automatica della memoria.

+0

Lo so. Ma cosa significa "Java allocare in quei 512m" esattamente? Questa memoria sembra non essere allocata in modo efficace dal momento che il mio sistema a 512 m di byte è in grado di avviare diverse altre applicazioni senza scambiare e reprot me che solo pochi megabyte vengono utilizzati dalla mia applicazione java. –

+1

Perché è stato downvoted? È tecnicamente corretto tranne che per l'ultima frase che può o non può essere corretta. In un mondo ad alte prestazioni è solitamente più intelligente avere java allocare tutta la memoria di cui avrà bisogno con un singolo brk(). In altre situazioni, allocare memoria mentre lo si utilizza potrebbe essere più intelligente. – Fredrik

+0

Non ho downvoted questa risposta me stesso. Per quanto riguarda il tuo commento ho la stessa domanda di quella che ho chiesto a dan: C'è qualche "rischio" o svantaggio nell'impostare il valore Xms sullo stesso valore di Xmx? Grazie Manu –

34

La JVM inizierà con l'uso della memoria a livello di heap iniziale. Se il maxheap è più alto, crescerà fino alla dimensione massima, poiché i requisiti di memoria superano la memoria corrente.

Quindi,

  • -Xms512m -Xmx512m

JVM inizia con 512 M, non ridimensiona.

  • -Xms64m -Xmx512m

JVM inizia con 64M, cresce (fino ad un massimo del soffitto di 512), se mem. i requisiti superano 64.

+0

Lo so. Ma come detto nel mio commento precedente, cosa significa "Java inizierà con l'utilizzo della memoria a livello di heap iniziale"?Questa memoria non sembra allocata in modo efficace dal momento che il mio sistema a 512 m di byte è in grado di avviare diverse altre applicazioni senza scambiare e riprovare che solo pochi megabyte vengono utilizzati dalla mia applicazione java. –

+3

In genere si imposta la dimensione heap iniziale su un valore maggiore se si sapeva che un'app all'avvio consumerebbe una particolare quantità di memoria. Ciò impedisce a JVM di dover prendere tempo di esecuzione all'avvio per ridimensionare l'heap un numero di volte. Questo particolare utilizzo è un'ottimizzazione molto comune per rendere Eclipse più veloce evitando il costoso ciclo di allocazione. – dhable

+0

Grazie per questa risposta che mi porta a quest'altra domanda: C'è qualche "rischio" o svantaggio nell'impostare il valore Xms sullo stesso valore di Xmx? –

5

La JVM ridimensiona l'heap in modo adattivo, nel senso che tenterà di trovare la dimensione dell'heap migliore per l'applicazione. -Xms e -Xmx specifica semplicemente l'intervallo in cui la JVM può operare e ridimensionare l'heap. Se -Xms e -Xmx hanno lo stesso valore, la dimensione dell'heap della JVM rimarrà costante a quel valore.

Generalmente è meglio impostare solo -Xmx e lasciare che la JVM trovi la migliore dimensione dell'heap, a meno che non vi sia un motivo specifico per cui è necessario fornire alla JVM un grande heap all'avvio di JVM.

Per quanto riguarda quando la JVM richiede effettivamente la memoria dal sistema operativo, credo che dipenda dalla piattaforma e dall'implementazione della JVM. Immagino che non richiederebbe la memoria finché la tua app non ne avesse effettivamente bisogno. -Xmx e -Xms si limitano a riservare la memoria.

14

Oltre a parametri Heap standard di -Xms e -Xmx è anche bene sapere -XX:PermSize e -XX:MaxPermSize, che viene utilizzato per specificare la dimensione dello spazio Perm Gen perché anche se si potrebbe avere spazio in altra generazione nel mucchio si può esaurire la memoria se il tuo perm gen space si riempie. Questo collegamento ha anche una bella panoramica di alcuni important JVM parameters.

0

Ho creato questo esempio giocattolo in scala, my_file.scala:

object MyObject { 

    def main(args: Array[String]) { 
     var ab = ArrayBuffer.empty[Int] 

     for (i <- 0 to 100 * 1000 * 1000) { 
      ab += i 
      if (i % 10000 == 0) { 
       println("On : %s".format(i)) 
      } 
     } 
    } 
} 

ho eseguito con:

scala -J-Xms500m -J-Xmx7g my_file.scala 

e

scala -J-Xms7g -J-Xmx7g my_file.scala 

ci sono sicuramente le pause notevoli nel -Xms500m versione. Sono certo che le brevi pause sono esecuzioni di raccolta dati inutili e quelle lunghe sono allocazioni di heap.