A questão não é sobre o tamanho máximo de heap em um sistema operacional de 32 bits, visto que os sistemas operacionais de 32 bits têm um tamanho máximo de memória endereçável de 4 GB e que o tamanho máximo de heap da JVM depende de quanta memória livre contígua pode ser reservada.
Estou mais interessado em saber o tamanho de heap máximo (teórico e prático) para uma JVM de 32 bits em execução em um sistema operacional de 64 bits. Basicamente, estou procurando respostas semelhantes às figuras em uma pergunta relacionada no SO .
Quanto ao motivo pelo qual uma JVM de 32 bits é usada em vez de uma de 64 bits, o motivo não é técnico, mas administrativo / burocrático - provavelmente é tarde demais para instalar uma JVM de 64 bits no ambiente de produção.
Você pode perguntar ao Java Runtime:
Isso relatará a "Memória máxima" com base na alocação de heap padrão. Portanto, você ainda precisa jogar com
-Xmx
(no HotSpot ). Descobri que rodando no Windows 7 Enterprise de 64 bits, minha JVM HotSpot de 32 bits pode alocar até 1577 MiB:Considerando que, com uma JVM de 64 bits no mesmo sistema operacional, é claro que é muito maior (cerca de 3TiB)
Como outros já mencionaram, depende do sistema operacional.
Para um sistema operacional host de 64 bits, se a JVM for de 32 bits, ela ainda dependerá, provavelmente como demonstrado acima.
- ATUALIZAÇÃO 20110905 : Eu só queria apontar algumas outras observações / detalhes:
Runtime.MaxMemory
que pode ser alocada também depende do conjunto de trabalho do sistema operacional . Uma vez eu executei isso enquanto também tinha o VirtualBox em execução e descobri que não conseguia iniciar o HotSpot JVM com-Xmx1590M
e tinha que diminuir. Isso também implica que você pode obter mais de 1590 MB, dependendo do tamanho do seu conjunto de trabalho no momento (embora eu ainda afirme que será inferior a 2 GiB para 32 bits por causa do design do Windows)fonte
Você não especifica qual sistema operacional.
No Windows (para meu aplicativo - um aplicativo de gerenciamento de risco de longa duração), observamos que não podíamos ir além de 1280 MB no Windows de 32 bits. Duvido que rodar uma JVM de 32 bits em 64 bits faça alguma diferença.
Portamos o aplicativo para Linux e estamos executando uma JVM de 32 bits em hardware de 64 bits e temos uma VM de 2,2 GB rodando com bastante facilidade.
O maior problema que você pode ter é o GC, dependendo para o que você está usando a memória.
fonte
De 4.1.2 Dimensionamento de heap :
Encontramos uma resposta muito boa aqui: memória máxima do Java no Windows XP .
fonte
Recentemente, tivemos alguma experiência com isso. Transferimos do Solaris (x86-64 versão 5.10) para o Linux (RedHat x86-64) recentemente e percebemos que temos menos memória disponível para um processo JVM de 32 bits no Linux do que Solaris.
Para Solaris, isso quase chega a 4 GB (http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit).
Executamos nosso aplicativo com -Xms2560m -Xmx2560m -XX: MaxPermSize = 512m -XX: PermSize = 512m sem problemas no Solaris nos últimos dois anos. Tentei movê-lo para o Linux e tivemos problemas com erros aleatórios de falta de memória na inicialização. Conseguimos apenas fazer com que ele inicializasse consistentemente em -Xms2300 -Xmx2300 . Então, fomos avisados disso pelo suporte.
fonte
As limitações de uma JVM de 32 bits em um sistema operacional de 64 bits serão exatamente as mesmas que as limitações de uma JVM de 32 bits em um sistema operacional de 32 bits. Afinal, o JVM de 32 bits será executado em uma máquina virtual de 32 bits (no sentido de virtualização), portanto, não saberá que está executando em um sistema operacional / máquina de 64 bits.
A única vantagem de executar uma JVM de 32 bits em um sistema operacional de 64 bits em comparação com um sistema operacional de 32 bits é que você pode ter mais memória física e, portanto, encontrará troca / paginação com menos frequência. No entanto, essa vantagem só é totalmente percebida quando você tem vários processos.
fonte
Quando eu estava trabalhando para a BEA, descobrimos que o aplicativo médio na verdade rodava mais devagar em uma JVM de 64 bits do que quando rodava em uma JVM de 32 bits. Em alguns casos, o impacto no desempenho chegou a ser 25% mais lento. Portanto, a menos que seu aplicativo realmente precise de toda aquela memória extra, seria melhor configurar mais servidores de 32 bits.
Pelo que me lembro, as três justificativas técnicas mais comuns para o uso de 64 bits que o pessoal de serviços profissionais da BEA encontrou foram:
.
fonte
O JROCKIT JVM atualmente de propriedade da Oracle oferece suporte ao uso de heap não contíguo, permitindo que o JVM de 32 bits acesse mais de 3,8 GB de memória quando o JVM está sendo executado em um sistema operacional Windows de 64 bits. (2,8 GB quando executado em um sistema operacional de 32 bits).
http://blogs.oracle.com/jrockit/entry/how_to_get_almost_3_gb_heap_on_windows
O JVM pode ser baixado gratuitamente (requer registro) em
http://www.oracle.com/technetwork/middleware/jrockit/downloads/index.html
fonte
Aqui estão alguns testes em Solaris e Linux de 64 bits
Solaris 10 - SPARC - máquina T5220 com 32 GB de RAM (e cerca de 9 GB de espaço livre)
BTW: Aparentemente, o Java não aloca muita memória real com a inicialização. Pareceu levar apenas cerca de 100 MB por instância iniciada (comecei 10)
Solaris 10 - x86 - VMWare VM com 8 GB de RAM (cerca de 3 GB livres *)
Os 3 GB de RAM livres não são verdadeiros. Há um grande pedaço de RAM que os caches ZFS usam, mas não tenho acesso root para verificar quanto exatamente
RedHat 5.5 - x86 - VMWare VM com 4 GB de RAM (cerca de 3,8 GB usados - 200 MB em buffers e 3,1 GB em caches, ou seja, cerca de 3 GB livres)
Mesma máquina usando JRE 7
fonte
Deve ser muito melhor
Para uma JVM de 32 bits em execução em um host de 64 bits, imagino que o que sobra para o heap será qualquer espaço virtual não fragmentado disponível após a JVM, suas próprias DLLs e qualquer material de compatibilidade do sistema operacional de 32 bits carregado. Eu acho que 3 GB deveria ser possível, mas o quanto isso é melhor depende de como você está se saindo em um host de 32 bits.
Além disso, mesmo se você pudesse fazer um heap gigante de 3 GB, você pode não querer, pois isso tornará as pausas do GC potencialmente problemáticas. Algumas pessoas simplesmente executam mais JVMs para usar a memória extra em vez de uma gigante. Eu imagino que eles estão ajustando o JVM agora para funcionar melhor com pilhas gigantes.
É um pouco difícil saber exatamente o quanto você pode fazer melhor. Eu acho que sua situação de 32 bits pode ser facilmente determinada por experimento. Certamente é difícil prever abstratamente, já que muitas coisas influenciam nisso, especialmente porque o espaço virtual disponível em hosts de 32 bits é bastante restrito. O heap precisa existir em memória virtual contígua, portanto, fragmentação do espaço de endereço para dll e uso interno do espaço de endereço pelo kernel do sistema operacional irão determinar o intervalo de alocações possíveis.
O SO usará parte do espaço de endereço para mapear dispositivos HW e suas próprias alocações dinâmicas. Embora essa memória não esteja mapeada no espaço de endereço do processo java, o kernel do sistema operacional não pode acessá-la e ao seu espaço de endereço ao mesmo tempo, portanto, limitará o tamanho do espaço virtual de qualquer programa.
O carregamento de DLLs depende da implementação e do lançamento da JVM. Carregar o kernel do SO depende de um grande número de coisas, o lançamento, o HW, quantas coisas ele mapeou até agora desde a última reinicialização, quem sabe ...
Em suma
Aposto que você obtém 1-2 GB em 32 bits e cerca de 3 em 64 bits, portanto, uma melhoria geral de cerca de 2x .
fonte
No Solaris, o limite é de cerca de 3,5 GB desde o Solaris 2.5. (cerca de 10 anos atrás)
fonte
Eu estava tendo os mesmos problemas com o JVM que o App Inventor para Android Blocks Editor usa. Ele define a pilha em 925 m máx. Isso não é suficiente, mas eu não poderia definir mais do que cerca de 1200m, dependendo de vários fatores aleatórios em minha máquina.
Eu baixei Nightly, o navegador beta de 64 bits do Firefox, e também a versão JAVA 7 de 64 bits.
Ainda não encontrei meu novo limite de heap, mas acabei de abrir uma JVM com tamanho de heap de 5900m . Sem problemas!
Estou executando o Win 7 64 bit Ultimate em uma máquina com 24 GB de RAM.
fonte
Eu tentei definir o tamanho do heap até 2200M em uma máquina Linux de 32 bits e a JVM funcionou bem. O JVM não começou quando eu o configurei para 2300M.
fonte
Este é um ajuste pesado, mas você pode obter um heap de 3 GB.
http://www.microsofttranslator.com/bv.aspx?from=&to=en&a=http://forall.ru-board.com/egor23/online/FAQ/Virtual_Memory/Limits_Virtual_Memory.html
fonte
mais um ponto aqui para JVM de ponto de acesso de 32 bits: - a capacidade de heap nativa = 4 Gig - Java Heap - PermGen;
Pode ser especialmente complicado para a JVM de 32 bits, pois o Java Heap e o Heap nativo estão em uma corrida. Quanto maior for o Heap Java, menor será o Heap nativo. A tentativa de configurar um grande Heap para uma VM de 32 bits, por exemplo, 2,5 GB +, aumenta o risco de OutOfMemoryError nativo, dependendo da área de cobertura de seu (s) aplicativo (s), número de Threads, etc.
fonte
A limitação também vem do fato de que para uma
32 bit
VM, oheap
próprio tem que começar no endereço zero se você quiser todos eles4GB
.Pense nisso, se você quiser fazer referência a algo por meio de:
ou seja: uma referência que tem essa representação de bits em particular, significa que você está tentando acessar a primeira memória do heap. Para que isso seja possível, o heap deve começar no endereço zero. Mas isso nunca acontece, começa em algum deslocamento de zero:
Como o heap nunca começa do endereço zero em um
OS
, há alguns bits que nunca são usados a partir de uma32
referência de bits e, como tal, o heap que pode ser referenciado é menor.fonte
Teórico 4gb, mas na prática (para IBM JVM):
Win 2k8 64, IBM Websphere Application Server 8.5.5 32 bits
C:\IBM\WebSphere\AppServer\bin>managesdk.bat -listAvailable -verbose CWSDK1003I: Доступные SDK: CWSDK1005I: Имя SDK: 1.6_32 - com.ibm.websphere.sdk.version.1.6_32=1.6 - com.ibm.websphere.sdk.bits.1.6_32=32 - com.ibm.websphere.sdk.location.1.6_32=${WAS_INSTALL_ROOT}/java - com.ibm.websphere.sdk.platform.1.6_32=windows - com.ibm.websphere.sdk.architecture.1.6_32=x86_32 - com.ibm.websphere.sdk.nativeLibPath.1.6_32=${WAS_INSTALL_ROOT}/lib/native/win /x86_32/ CWSDK1001I: Задача managesdk выполнена успешно. C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2036 MaxMemory JVMJ9GC017E -Xmx слишком мала, должна быть не меньше 1 M байт JVMJ9VM015W Ошибка инициализации для библиотеки j9gc26(2): Не удалось инициализи ровать Could not create the Java virtual machine. C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2047M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 2146435072 (2047.0 MiB) Free Memory: 3064536 (2.9225692749023438 MiB) C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2048M MaxMemory JVMJ9VM015W Ошибка инициализации для библиотеки j9gc26(2): Не удалось создать эк земпляр кучи; запрошено 2G Could not create the Java virtual machine.
RHEL 6.4 64, IBM Websphere Application Server 8.5.5 32 bits
[bin]./java -Xmx3791M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 3975151616 (3791.0 MiB) Free Memory: 3232992 (3.083221435546875 MiB) [root@nagios1p bin]# ./java -Xmx3793M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 3977248768 (3793.0 MiB) Free Memory: 3232992 (3.083221435546875 MiB) [bin]# /opt/IBM/WebSphere/AppServer/bin/managesdk.sh -listAvailable -verbose CWSDK1003I: Available SDKs : CWSDK1005I: SDK name: 1.6_32 - com.ibm.websphere.sdk.version.1.6_32=1.6 - com.ibm.websphere.sdk.bits.1.6_32=32 - com.ibm.websphere.sdk.location.1.6_32=${WAS_INSTALL_ROOT}/java - com.ibm.websphere.sdk.platform.1.6_32=linux - com.ibm.websphere.sdk.architecture.1.6_32=x86_32 -com.ibm.websphere.sdk.nativeLibPath.1.6_32=${WAS_INSTALL_ROOT}/lib/native/linux/x86_32/ CWSDK1001I: Successfully performed the requested managesdk task.
fonte