Come viene determinata la dimensione massima dell'heap Java predefinita?


421

Se ometto l' -Xmxnopzione dalla riga di comando Java, verrà utilizzato un valore predefinito. Secondo la documentazione Java

"il valore predefinito viene scelto in fase di esecuzione in base alla configurazione del sistema"

Quali impostazioni di configurazione del sistema influenzano il valore predefinito?


1
configurazione del sistema significa: a) client jvm vs server jvm b) 32 bit vs 64 bit. Collegamenti: 1) aggiornamento da J2SE5.0 docs.oracle.com/javase/6/docs/technotes/guides/vm/… 2) risposta breve: docs.oracle.com/javase/8/docs/technotes/guides/vm / gctuning /… 3) risposta dettagliata: docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/… 4) client vs server: javacodegeeks.com/2011/07/jvm-options-client- vs-server.html
Vyshnav Ramesh Thrissur

2
è difficile da capire dai link sopra. Quindi riassumendoli qui: la dimensione massima dell'heap per Client jvm è 256mb (c'è un'eccezione, letta dai collegamenti sopra). La dimensione massima dell'heap per Server jvm di 32 bit è 1 gb e di 64 bit è 32 gb (anche in questo caso ci sono eccezioni. Leggere gentilmente dai link). Quindi i suoi
256 MB

Risposte:


507

Su Windows, è possibile utilizzare il comando seguente per scoprire le impostazioni predefinite sul sistema in cui sono in esecuzione le applicazioni.

java -XX: + PrintFlagsFinal -version | findstr HeapSize

Cerca le opzioni MaxHeapSize(per -Xmx) e InitialHeapSizeper -Xms.

Su un sistema Unix / Linux, puoi farlo

java -XX: + PrintFlagsFinal -version | grep HeapSize

Credo che l'output risultante sia in byte.


3
Speravo in una bella opzione come questa, ma non ha funzionato per me usando la Java 6 VM di IBM.
Matt Lavin,

Grande! Posso giocare con tutte queste opzioni predefinite? Qual è la variabile ENV corrispondente per ciascuna?
Elista,

28
Nel mio caso su Linux, InitialHeapSize = 262803264e MaxHeapSize = 4206886912che è di circa 256 MB e 4 GB , se non mi sbaglio. Questo significa che ogni JVM inizia come se fosse stata lanciata con -Xms256m -Xmx4gopzioni?
Yuriy Nakonechnyy,

9
Su un sistema Windows:java -XX:+PrintFlagsFinal -version | findstr /R /C:"HeapSize"
sp00m,

1
@matanster Sul mio Linux -versionsopprime il lungo "utilizzo" del testo stderr.
Franklin Yu,

115

Per Java SE 5: Secondo Garbage Collector Ergonomics [Oracle] :

dimensione iniziale dell'heap:

Più grande di 1/64 della memoria fisica della macchina sulla macchina o un minimo ragionevole. Prima di J2SE 5.0, la dimensione heap iniziale predefinita era un minimo ragionevole, che varia in base alla piattaforma. È possibile ignorare questa impostazione predefinita utilizzando l'opzione della riga di comando -Xms.

dimensione massima dell'heap:

Più piccolo di 1/4 della memoria fisica o 1 GB. Prima di J2SE 5.0, la dimensione heap massima predefinita era 64 MB. È possibile ignorare questa impostazione predefinita utilizzando l'opzione della riga di comando -Xmx.

AGGIORNARE:

Come sottolineato da Tom Anderson nel suo commento, quanto sopra è per macchine di classe server. Dal ergonomia nella macchina virtuale 5.0 JavaTM :

Nella piattaforma J2SE versione 5.0 è stata definita una macchina con classe denominata macchina di classe server

  • 2 o più processori fisici
  • 2 o più Gbyte di memoria fisica

ad eccezione delle piattaforme a 32 bit che eseguono una versione del sistema operativo Windows. Su tutte le altre piattaforme i valori predefiniti sono gli stessi dei valori predefiniti per la versione 1.4.2.

Nella piattaforma J2SE versione 1.4.2 per impostazione predefinita sono state effettuate le seguenti selezioni

  • heap iniziale di 4 Mbyte
  • dimensione massima dell'heap di 64 MByte

4
Avvertenza: è per macchine di classe server, non di classe client. Devi leggere quel documento insieme a java.sun.com/docs/hotspot/gc5.0/ergo5.html che definisce quei termini e cosa succede ai computer di classe client. dogbane, potrei umilmente suggerirti di modificare la tua risposta per citare i passaggi pertinenti?
Tom Anderson,

3
Questo è un valore ridicolmente basso nel 2012. Pochissime applicazioni serie si adattano a 64 megabyte.
Mark E. Haase,

1
Vedi la risposta di Ernesto del 30 ottobre 2012 per le macchine client dopo l'aggiornamento di Java 6 18.
Andy Thomas,

Ricorda inoltre che dice: "I limiti e le frazioni fornite per la dimensione dell'heap sono corretti per J2SE 5.0. È probabile che siano diversi nelle versioni successive man mano che i computer diventano più potenti".
Lodovik,

A proposito, questo algo è solo per Parallel Garbage Collector.
Mike Argyriou,

45

Java 8 vuole più di 1/64 ° della vostra memoria fisica per il vostro xmssize (HEAPSIZE Minimo) e meno di 1/4 ° della vostra memoria fisica per il vostro -Xmxsize (Massimo HEAPSIZE).

È possibile verificare la dimensione heap Java predefinita :

In Windows :

java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"

In Linux :

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'

Quali impostazioni di configurazione del sistema influenzano il valore predefinito?

La memoria fisica della macchina e la versione Java.


5
non è 1/64 anziché 1/6?
Vyshnav Ramesh Thrissur

1
Sì, Xmssize (Minimum HeapSize / InitialHeapSize) è più di 1/64 della tua memoria fisica e Xmxsize (Maximum HeapSize / MaxHeapSize) è meno di 1/4 della tua memoria fisica. (Ad esempio per il mio mac, con 16 GB di RAM, sto ottenendo uintx InitialHeapSize: = 268435456 {product} uintx MaxHeapSize: = 4294967296 {product}, i, e Xms è 268 MB e Xmx è 4,29 GB
sjethvani,

1
Modifica la risposta È 1/64, non 1/6.
emeraldhieu,

35

Questo è cambiato nell'aggiornamento 18 di Java 6 .

Supponendo che abbiamo più di 1 GB di memoria fisica (abbastanza comune in questi giorni), è sempre 1/4 della tua memoria fisica per il server VM.


8
Inesatto, la pagina collegata dicegreater than or equal to 1 gigabyte of physical memory results in a maximum heap size of 256 megabytes
Paolo Fulgoni,

5
Ho appena controllato su una macchina Linux con memoria fisica da 5 GB. Predefinito spettacoli max heap come 1.5GB
ernesto

1
@PaoloFulgoni no, un altro esempio pratico che osservo in questo momento: 129 Gbyte di memoria fisica danno come risultato 32 Gbyte di dimensione heap massima
Kirill

Si veda la risposta di APL per il motivo per cui questo è giusto: stackoverflow.com/a/13310792/32453 Vedi anche stackoverflow.com/a/56036202/32453
rogerdpack

16

Ernesto ha ragione. Secondo il link che ha pubblicato [1]:

Configurazione heap JVM client aggiornata

Nel client JVM ...

  • La dimensione heap massima predefinita è metà della memoria fisica fino a una dimensione della memoria fisica di 192 megabyte e in caso contrario un quarto della memoria fisica fino a una dimensione della memoria fisica di 1 gigabyte.

    Ad esempio, se la macchina ha 128 megabyte di memoria fisica, la dimensione massima dell'heap è 64 megabyte e una memoria fisica maggiore o uguale a 1 gigabyte comporta una dimensione heap massima di 256 megabyte.

  • La dimensione heap massima non viene effettivamente utilizzata da JVM a meno che il programma non crei abbastanza oggetti per richiederlo. Una quantità molto più piccola, definita dimensione heap iniziale, viene allocata durante l'inizializzazione JVM. ...

  • ...
  • L'ergonomia di configurazione dell'heap JVM del server è ora la stessa del client, tranne per il fatto che la dimensione heap massima predefinita per le JVM a 32 bit è 1 gigabyte , corrispondente a una dimensione della memoria fisica di 4 gigabyte e per le JVM a 64 bit è 32 gigabyte , corrispondente con una dimensione di memoria fisica di 128 gigabyte.

[1] http://www.oracle.com/technetwork/java/javase/6u18-142093.html



8

Finalmente!

A partire da Java 8u191 ora hai le opzioni:

-XX:InitialRAMPercentage
-XX:MaxRAMPercentage
-XX:MinRAMPercentage

che può essere utilizzato per dimensionare l'heap come percentuale della RAM fisica utilizzabile. (che è uguale alla RAM installata meno di quanto utilizza il kernel).

Vedere le Note di rilascio per Java8 u191 per ulteriori informazioni. Nota che le opzioni sono menzionate sotto un'intestazione Docker ma in realtà si applicano sia in ambiente Docker che in un ambiente tradizionale.

Il valore predefinito per MaxRAMPercentageè 25%. Questo è estremamente conservativo.

La mia regola: se il tuo host è più o meno dedicato all'esecuzione della determinata applicazione java, allora puoi senza problemi aumentare notevolmente. Se sei su Linux, esegui solo demoni standard e hai installato la RAM da qualche parte intorno a 1 GB e oltre, non esiterei a utilizzare il 75% per l'heap della JVM. Ancora una volta, ricorda che questo è il 75% della RAM disponibile , non la RAM installata . Ciò che rimane sono gli altri processi di terra dell'utente che potrebbero essere in esecuzione sull'host e gli altri tipi di memoria necessari alla JVM (ad esempio per lo stack). Tutti insieme, questo si adatterà perfettamente al 25% rimasto. Ovviamente, con ancora più RAM installata, il 75% è una scommessa sempre più sicura. (Vorrei che la gente del JDK avesse implementato un'opzione in cui si potesse specificare una scala)

L'impostazione MaxRAMPercentagedell'opzione è simile alla seguente:

java -XX:MaxRAMPercentage=75.0  ....

Si noti che questi valori percentuali sono di tipo "doppio" e pertanto è necessario specificarli con un punto decimale. Si ottiene un errore un po 'strano se si utilizza "75" anziché "75.0".


7

il valore predefinito viene scelto in fase di esecuzione in base alla configurazione del sistema

Dai un'occhiata alla pagina della documentazione

Dimensione heap predefinita

A meno che le dimensioni dell'heap iniziale e massima non siano specificate nella riga di comando, vengono calcolate in base alla quantità di memoria sulla macchina.

  1. Dimensioni di heap iniziali e massime predefinite JVM client:

    La dimensione heap massima predefinita è metà della memoria fisica fino a una dimensione della memoria fisica di 192 megabyte (MB) e in caso contrario un quarto della memoria fisica fino a una dimensione della memoria fisica di 1 gigabyte (GB) .

  2. Dimensioni dell'heap iniziale e massimo predefinite JVM del server:

    Nelle JVM a 32 bit, la dimensione heap massima predefinita può essere fino a 1 GB se la memoria fisica è pari o superiore a 4 GB . Nelle JVM a 64 bit, la dimensione heap massima predefinita può essere fino a 32 GB se la memoria fisica è di almeno 128 GB

Quali impostazioni di configurazione del sistema influenzano il valore predefinito?

È possibile specificare la dimensione iniziale e massima dell'heap usando i flag -Xms (dimensione iniziale dell'heap) e -Xmx (dimensione massima dell'heap). Se sai quanto heap deve funzionare correttamente per l'applicazione, puoi impostare -Xms e -Xmx sullo stesso valore


5

I Xmse Xmxsono flag della Java virtual machine (JVM):

  • Xms: initial and minimumJVMheap size
    • Format: -Xmx<size>[g|G|m|M|k|K]
    • Default Size:
      • -server modalità: 25% di memoria fisica libera,> = 8 MB e <= 64 MB
      • -client mode: 25% di memoria fisica libera,> = 8 MB e <= 16 MB
    • Typical Size:
      • -Xms128M
      • -Xms256M
      • -Xms512M
    • Function/ Effect:
      • -> JVM inizia con l'allocazione delle Xmsdimensioni della memoria
  • Xmx: maximumJVMheap size
    • Format: -Xmx<size>[g|G|m|M|k|K]
    • Default Size:
      • <= R27.2
        • Windows: 75%della memoria fisica totale fino a1GB
        • Linux/Solaris: 50%di memoria fisica disponibile fino a1GB
      • >= R27.3
        • Windows X64: 75%della memoria fisica totale fino a2GB
        • Linux/Solaris X64: 50%di memoria fisica disponibile fino a2GB
        • Windows x86: 75%della memoria fisica totale fino a1GB
        • Linux/Solaris X86: 50%di memoria fisica disponibile fino a1GB
    • Typical Size:
      • -Xmx1g
      • -Xmx2084M
      • -Xmx4g
      • -Xmx6g
      • -Xmx8g
    • Function/ Effect:
      • -> JVM consente l'utilizzo di Xmxmemoria di dimensioni massime
        • quando supera Xmx, lo faràjava.lang.OutOfMemoryError
          • Come riparare OutOfMemoryError?
            • superare il Xmxvalore
              • es: da -Xmx4ga-Xmx8g

Più dettaglio

consultare il documento ufficiale: -X Opzioni della riga di comando


Non è per la JRockit JVM? (al contrario dell'Hotspot JVM di Oracle)
peterh

4

Numerosi parametri influenzano la dimensione della generazione. Il diagramma seguente illustra la differenza tra spazio dedicato e spazio virtuale nell'heap. All'inizializzazione della macchina virtuale, l'intero spazio per l'heap è riservato. La dimensione dello spazio riservato può essere specificata con l' -Xmxopzione. Se il valore del -Xmsparametro è inferiore al valore del -Xmxparametro, non tutto lo spazio riservato viene immediatamente assegnato alla macchina virtuale. Lo spazio non assegnato è etichettato "virtuale" in questa figura. Le diverse parti dell'heap (generazione permanente, generazione in carica e generazione in giovane età) possono crescere fino al limite dello spazio virtuale, se necessario.

inserisci qui la descrizione dell'immagine

Per impostazione predefinita, la macchina virtuale aumenta o riduce l'heap in ogni raccolta per cercare di mantenere la proporzione di spazio libero per vivere gli oggetti in ogni raccolta all'interno di un intervallo specifico. Questo intervallo target è impostato come percentuale dai parametri XX:MinHeapFreeRatio=<minimum>e -XX:MaxHeapFreeRatio=<maximum>, e la dimensione totale è limitata da -Xms<min>e sopra da -Xmx<max>.

Parametro Valore predefinito

MinHeapFreeRatio 40

MaxHeapFreeRatio 70

-Xms 3670k

-Xmx 64m

I valori predefiniti dei parametri delle dimensioni dell'heap su sistemi a 64 bit sono stati ridimensionati di circa il 30%. Questo aumento ha lo scopo di compensare la maggiore dimensione degli oggetti su un sistema a 64 bit.

Con questi parametri, se la percentuale di spazio libero in una generazione scende al di sotto del 40%, la generazione verrà espansa per mantenere il 40% di spazio libero, fino alla dimensione massima consentita della generazione. Allo stesso modo, se lo spazio libero supera il 70%, la generazione verrà contratta in modo che solo il 70% dello spazio sia libero, soggetto alle dimensioni minime della generazione.

Spesso le applicazioni server di grandi dimensioni presentano due problemi con queste impostazioni predefinite. Uno è l'avvio lento, perché l'heap iniziale è piccolo e deve essere ridimensionato su molte raccolte principali. Un problema più urgente è che la dimensione massima dell'heap predefinita è irragionevolmente piccola per la maggior parte delle applicazioni server. Le regole empiriche per le applicazioni server sono:

  • A meno che tu non abbia problemi con le pause, prova a concedere più memoria possibile alla macchina virtuale. La dimensione predefinita (64 MB) è spesso troppo piccola.
  • L'impostazione di -Xms e -Xmx sullo stesso valore aumenta la prevedibilità rimuovendo la decisione di dimensionamento più importante dalla macchina virtuale. Tuttavia, la macchina virtuale non è in grado di compensare se si effettua una scelta errata.
  • In generale, aumentare la memoria man mano che si aumenta il numero di processori, poiché l'allocazione può essere parallelizzata.

    C'è l' articolo completo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.