Como é determinado o tamanho máximo padrão do heap Java?

421

Se eu omitir a -Xmxnopção da linha de comando Java, um valor padrão será usado. De acordo com a documentação Java

"o valor padrão é escolhido no tempo de execução com base na configuração do sistema"

Quais configurações do sistema influenciam o valor padrão?

Richard Dorman
fonte
1
configuração do sistema significa: a) cliente jvm vs servidor jvm b) 32 bits vs 64 bits. Links: 1) atualização do J2SE5.0 docs.oracle.com/javase/6/docs/technotes/guides/vm/… 2) resposta breve: docs.oracle.com/javase/8/docs/technotes/guides/vm / gctuning /… 3) resposta detalhada: docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/… 4) cliente versus servidor: javacodegeeks.com/2011/07/jvm-options-client- vs-server.html
Vyshnav Ramesh Thrissur
2
é difícil de entender pelos links acima. Resumindo-os aqui: O tamanho máximo do heap para o cliente jvm é 256mb (há uma exceção, leia os links acima). O tamanho máximo de heap para o servidor jvm de 32 bits é de 1 gb e de 64 bits é de 32 gb (novamente há exceções aqui também. Leia isso nos links). Portanto, a sua 256MB ou 1GB ou 32gb
Vyshnav Ramesh Thrissur
Veja também stackoverflow.com/a/56036202/32453
rogerdpack

Respostas:

507

No Windows, você pode usar o seguinte comando para descobrir os padrões no sistema em que seus aplicativos são executados.

java -XX: + PrintFlagsFinal -version | findstr HeapSize

Procure as opções MaxHeapSize(para -Xmx) e InitialHeapSizepara -Xms.

Em um sistema Unix / Linux, você pode fazer

java -XX: + PrintFlagsFinal -version | grep HeapSize

Eu acredito que a saída resultante é em bytes.

stones333
fonte
3
Eu esperava uma opção legal como essa, mas não funcionou para mim usando o Java 6 VM da IBM.
precisa
Ótimo! Posso jogar com todas essas opções padrão? Qual é a variável ENV correspondente para cada um?
Elist
28
No meu caso no Linux, InitialHeapSize = 262803264e MaxHeapSize = 4206886912que tem cerca de 256 MB e 4 GB, se não me engano. Isso significa que toda JVM inicia como se tivesse sido lançada com -Xms256m -Xmx4gopções?
Yuriy Nakonechnyy
9
Em um sistema Windows:java -XX:+PrintFlagsFinal -version | findstr /R /C:"HeapSize"
sp00m 14/04/2015
1
@matanster No meu Linux, -versionsuprime o longo "uso" do texto stderr.
Franklin Yu
115

Para Java SE 5: de acordo com a ergonomia do coletor de lixo [Oracle] :

tamanho inicial da pilha:

Maior de 1/64 da memória física da máquina ou um mínimo razoável. Antes do J2SE 5.0, o tamanho inicial padrão do heap era um mínimo razoável, que varia de acordo com a plataforma. Você pode substituir esse padrão usando a opção de linha de comando -Xms.

tamanho máximo de heap:

Menor de 1/4 da memória física ou 1 GB. Antes do J2SE 5.0, o tamanho máximo padrão do heap era de 64 MB. Você pode substituir esse padrão usando a opção de linha de comando -Xmx.

ATUALIZAR:

Como apontado por Tom Anderson em seu comentário, o acima é para máquinas de classe de servidor. Da ergonomia na máquina virtual JavaTM 5.0 :

Na plataforma J2SE versão 5.0, uma classe de máquina referida como uma classe de servidor foi definida como uma máquina com

  • 2 ou mais processadores físicos
  • 2 ou mais Gbytes de memória física

com exceção das plataformas de 32 bits que executam uma versão do sistema operacional Windows. Em todas as outras plataformas, os valores padrão são os mesmos que os valores padrão para a versão 1.4.2.

Na plataforma J2SE versão 1.4.2, por padrão, as seguintes seleções foram feitas

  • tamanho de heap inicial de 4 MB
  • tamanho máximo de heap de 64 MB
dogbane
fonte
4
Advertência: isso é para máquinas da classe servidor, não para a classe cliente. Você precisa ler esse documento em conjunto com java.sun.com/docs/hotspot/gc5.0/ergo5.html, que define esses termos e o que acontece com as máquinas da classe cliente. dogbane, posso humildemente sugerir que você edite sua resposta para citar as passagens relevantes?
Tom Anderson
3
Esse é um padrão ridiculamente baixo em 2012. Muito poucas aplicações sérias cabem dentro de 64 megabytes.
Mark E. Haase
1
Veja Ernesto 30 out 2012 resposta para máquinas cliente após Java 6 update 18.
Andy Thomas
Lembre-se também de que diz: "Os limites e frações fornecidos para o tamanho da pilha estão corretos para o J2SE 5.0. Eles provavelmente serão diferentes nas versões subsequentes à medida que os computadores ficarem mais poderosos".
Lodovik 27/10/2015
A propósito, esse algo é apenas para o Parallel Garbage Collector.
Mike Argyriou
45

Java 8 leva mais de 1/64 de sua memória física para o seu xmssize (HEAPSIZE mínima) e menos de 1 / 4th de sua memória física para o seu -Xmxsize (Maximum HEAPSIZE).

Você pode verificar o tamanho padrão do heap Java :

No Windows :

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

No Linux :

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

Quais configurações do sistema influenciam o valor padrão?

A memória física da máquina e a versão Java.

Sarat Chandra
fonte
5
não é 1/64 em vez de 1/6?
Vyshnav Ramesh Thrissur
1
Sim, Xmssize (mínimo HeapSize / InitialHeapSize) é mais que 1/64 da sua memória física e Xmxsize (máximo HeapSize / MaxHeapSize) é menor que 1/4 da sua memória física. (For-ex para o meu mac, tendo RAM 16GB, estou ficando uintx InitialHeapSize: = 268435456 {produto} uintx MaxHeapSize: = 4294967296 {produto}, i, e Xms é 268 MB & Xmx é 4,29 GB
sjethvani
1
Por favor edite a resposta. É 1/64, não 1/6.
Emeraldhieu 15/10/19
35

Isso foi alterado na atualização 18 do Java 6 .

Supondo que tenhamos mais de 1 GB de memória física (bastante comum atualmente), é sempre 1/4 da sua memória física para o servidor vm.

Ernesto
fonte
8
Incorreto, a página vinculada dizgreater than or equal to 1 gigabyte of physical memory results in a maximum heap size of 256 megabytes
Paolo Fulgoni
5
Acabei de verificar em uma máquina Linux com 5 GB de memória física. O heap máximo padrão é exibido como 1,5 GB
ernesto
1
@PaoloFulgoni não, outro exemplo prático que observo agora: 129 Gbytes de memória física resultam em 32 Gbytes de tamanho máximo de heap
Kirill
Veja a resposta da
apl para saber
16

Ernesto está certo. De acordo com o link que ele postou [1]:

Configuração de heap da JVM do cliente atualizada

Na JVM do cliente ...

  • O tamanho máximo padrão do heap é metade da memória física até 192 megabytes e, caso contrário, um quarto da memória física até 1 gigabyte.

    Por exemplo, se sua máquina tiver 128 megabytes de memória física, o tamanho máximo de heap é 64 megabytes e maior ou igual a 1 gigabyte de memória física resultará em um tamanho máximo de heap de 256 megabytes.

  • O tamanho máximo do heap não é realmente usado pela JVM, a menos que seu programa crie objetos suficientes para requerê-lo. Uma quantidade muito menor, denominada tamanho de heap inicial, é alocada durante a inicialização da JVM. ...

  • ...
  • A ergonomia da configuração de heap da JVM do servidor agora é a mesma do Cliente, exceto que o tamanho máximo padrão de heap para JVMs de 32 bits é de 1 gigabyte , correspondendo a um tamanho de memória física de 4 gigabytes e para JVMs de 64 bits é de 32 gigabytes , correspondente para um tamanho de memória física de 128 gigabytes.

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

apl
fonte
8

Finalmente!

A partir do Java 8u191, agora você tem as opções:

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

que pode ser usado para dimensionar o heap como uma porcentagem da RAM física utilizável. (que é o mesmo que a RAM instalada menos o que o kernel usa).

Consulte as Notas da versão do Java8 u191 para obter mais informações. Observe que as opções são mencionadas em um cabeçalho do Docker, mas na verdade elas se aplicam se você estiver no ambiente do Docker ou em um ambiente tradicional.

O valor padrão para MaxRAMPercentageé 25%. Isso é extremamente conservador.

Minha própria regra: se o seu host é mais ou menos dedicado à execução do aplicativo java fornecido, você pode, sem problemas, aumentar drasticamente. Se você estiver no Linux, executando apenas daemons padrão e tiver instalado RAM a partir de 1 Gb ou mais, não hesitaria em usar 75% para o heap da JVM. Novamente, lembre-se de que isso representa 75% da RAM disponível , não a RAM instalada . O que resta são os outros processos de terra do usuário que podem estar em execução no host e os outros tipos de memória que a JVM precisa (por exemplo, para a pilha). No conjunto, isso normalmente se encaixa perfeitamente nos 25% restantes. Obviamente, com ainda mais RAM instalada, os 75% são uma aposta mais segura. (Eu gostaria que o pessoal do JDK tivesse implementado uma opção em que você pudesse especificar uma escada)

Definir a MaxRAMPercentageopção fica assim:

java -XX:MaxRAMPercentage=75.0  ....

Observe que esses valores percentuais são do tipo 'duplo' e, portanto, você deve especificá-los com um ponto decimal. Você recebe um erro um tanto estranho se usar "75" em vez de "75.0".

peterh
fonte
7

o valor padrão é escolhido em tempo de execução com base na configuração do sistema

Dê uma olhada na página de documentação

Tamanho padrão do heap

A menos que os tamanhos de heap inicial e máximo sejam especificados na linha de comando, eles são calculados com base na quantidade de memória na máquina.

  1. Tamanhos de heap inicial e máximo padrão da JVM do cliente:

    O tamanho máximo de heap padrão é metade da memória física até 192 megabytes (MB) e, caso contrário, um quarto da memória física até 1 gigabyte (GB) .

  2. Tamanhos de heap inicial e máximo padrão da JVM do servidor:

    Nas JVMs de 32 bits, o tamanho máximo de heap padrão pode ser de até 1 GB se houver 4 GB ou mais de memória física . Nas JVMs de 64 bits, o tamanho máximo de heap padrão pode ser de até 32 GB se houver 128 GB ou mais de memória física

Quais configurações do sistema influenciam o valor padrão?

Você pode especificar os tamanhos de heap inicial e máximo usando os sinalizadores -Xms (tamanho de heap inicial) e -Xmx (tamanho de heap máximo). Se você sabe quanto heap seu aplicativo precisa para funcionar bem, você pode definir -Xms e -Xmx com o mesmo valor

Ravindra babu
fonte
5

O sinalizador Xmse Xmxé da Java virtual machine (JVM):

  • Xms: initial and minimumJVMheap size
    • Format: -Xmx<size>[g|G|m|M|k|K]
    • Default Size:
      • -server modo: 25% de memória física livre,> = 8MB e <= 64MB
      • -client mode: 25% de memória física livre,> = 8MB e <= 16MB
    • Typical Size:
      • -Xms128M
      • -Xms256M
      • -Xms512M
    • Function/ Effect:
      • -> JVM iniciar com alocar Xmstamanho de memória
  • Xmx: maximumJVMheap size
    • Format: -Xmx<size>[g|G|m|M|k|K]
    • Default Size:
      • <= R27.2
        • Windows: 75%da memória física total até1GB
        • Linux/Solaris: 50%de memória física disponível até1GB
      • >= R27.3
        • Windows X64: 75%da memória física total até2GB
        • Linux/Solaris X64: 50%de memória física disponível até2GB
        • Windows x86: 75%da memória física total até1GB
        • Linux/Solaris X86: 50%de memória física disponível até1GB
    • Typical Size:
      • -Xmx1g
      • -Xmx2084M
      • -Xmx4g
      • -Xmx6g
      • -Xmx8g
    • Function/ Effect:
      • -> JVM permitem o uso máximo de Xmxmemória de tamanho
        • quando exceder Xmx, serájava.lang.OutOfMemoryError
          • Como consertar OutOfMemoryError?
            • exceder Xmxvalor
              • por exemplo: de -Xmx4gpara-Xmx8g

Mais detalhes

consulte o documento oficial: -X Opções da linha de comando

crifan
fonte
Isso não é para o JRockit JVM? (em oposição ao Hotspot JVM da Oracle)
peterh 11/09/19
4

Vários parâmetros afetam o tamanho da geração. O diagrama a seguir ilustra a diferença entre espaço confirmado e espaço virtual no heap. Na inicialização da máquina virtual, todo o espaço para o heap é reservado. O tamanho do espaço reservado pode ser especificado com a -Xmxopção Se o valor do -Xmsparâmetro for menor que o valor do -Xmxparâmetro, nem todo o espaço reservado será imediatamente comprometido com a máquina virtual. O espaço não confirmado é rotulado como "virtual" nesta figura. As diferentes partes da pilha (geração permanente, geração assegurada e geração jovem) podem crescer até o limite do espaço virtual, conforme necessário.

insira a descrição da imagem aqui

Por padrão, a máquina virtual aumenta ou diminui o heap em cada coleção para tentar manter a proporção de espaço livre para viver objetos em cada coleção dentro de um intervalo específico. Esse intervalo de destino é definido como uma porcentagem pelos parâmetros - XX:MinHeapFreeRatio=<minimum>e -XX:MaxHeapFreeRatio=<maximum>, e o tamanho total é limitado abaixo por -Xms<min>e acima de -Xmx<max>.

Valor padrão do parâmetro

MinHeapFreeRatio 40

MaxHeapFreeRatio 70

-Xms 3670k

-Xmx 64m

Os valores padrão dos parâmetros de tamanho de heap em sistemas de 64 bits foram aumentados em aproximadamente 30%. Esse aumento visa compensar o tamanho maior de objetos em um sistema de 64 bits.

Com esses parâmetros, se a porcentagem de espaço livre em uma geração cair abaixo de 40%, a geração será expandida para manter 40% de espaço livre, até o tamanho máximo permitido da geração. Da mesma forma, se o espaço livre exceder 70%, a geração será contratada para que apenas 70% do espaço seja livre, sujeito ao tamanho mínimo da geração.

Aplicativos de servidor grandes geralmente enfrentam dois problemas com esses padrões. Uma é a inicialização lenta, porque o heap inicial é pequeno e deve ser redimensionado em muitas coleções principais. Um problema mais urgente é que o tamanho máximo padrão do heap é excessivamente pequeno para a maioria dos aplicativos de servidor. As regras práticas para aplicativos de servidor são:

  • A menos que você tenha problemas com pausas, tente conceder o máximo de memória possível à máquina virtual. O tamanho padrão (64 MB) geralmente é muito pequeno.
  • Definir -Xms e -Xmx com o mesmo valor aumenta a previsibilidade, removendo a decisão de dimensionamento mais importante da máquina virtual. No entanto, a máquina virtual não poderá compensar se você fizer uma má escolha.
  • Em geral, aumente a memória à medida que aumenta o número de processadores, pois a alocação pode ser paralelizada.

    Existe o artigo completo

theodor
fonte