Taille maximale du tas Java d'une JVM 32 bits sur un système d'exploitation 64 bits


La question ne concerne pas la taille maximale du tas sur un système d'exploitation 32 bits, étant donné que les systèmes d'exploitation 32 bits ont une taille de mémoire adressable maximale de 4 Go et que la taille maximale du tas de la JVM dépend de la quantité de mémoire libre contiguë pouvant être réservée.

Je suis plus intéressé à connaître la taille maximale (à la fois théorique et pratiquement réalisable) du tas pour une JVM 32 bits fonctionnant dans un système d'exploitation 64 bits. Fondamentalement, je regarde des réponses similaires à les chiffres d'une question connexe sur SO.

Comme pourquoi une JVM 32 bits est utilisé au lieu de 64-bit, la raison n'est pas technique, mais plutôt administrative et bureaucratique, il est probablement trop tard pour installer une JVM 64 bits dans l'environnement de production.

Author: Community, 2009-09-16

16 answers

Les JVM 32 bits qui s'attendent à avoir un seul gros morceau de mémoire et à utiliser des pointeurs bruts ne peuvent pas utiliser plus de 4 Go (car c'est la limite de 32 bits qui s'applique également aux pointeurs). Cela inclut Sun et - j'en suis sûr-aussi des implémentations IBM. Je ne sais pas si, par exemple, JRockit ou d'autres ont une grande option de mémoire avec leurs implémentations 32 bits.

Si vous prévoyez d'atteindre cette limite, vous devriez fortement envisager de démarrer une piste parallèle validant une JVM 64 bits pour votre environnement de production de sorte que vous avez cela prêt pour lorsque l'environnement 32 bits tombe en panne. Sinon, vous devrez le faire travailler sous pression, ce qui n'est jamais agréable.


Modifier 2014-05-15: Oracle FAQ:

La limite théorique maximale de tas pour la JVM 32 bits est 4G. En raison de diverses contraintes supplémentaires telles que le swap disponible, l'utilisation de l'espace d'adressage du noyau, la fragmentation de la mémoire et la surcharge des machines virtuelles, en pratique, la limite peut être beaucoup plus faible. Sur la plupart des fenêtres 32 bits modernes systèmes la taille maximale du tas varie de 1,4 G à 1,6 G. Sur les noyaux Solaris 32 bits, l'espace d'adressage est limité à 2G. Sur les systèmes d'exploitation 64 bits exécutant la machine virtuelle 32 bits, la taille maximale du tas peut être plus élevée, approchant la 4G sur de nombreux systèmes Solaris.

(http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit)

 62
Author: Thorbjørn Ravn Andersen, 2017-08-04 10:36:43

Vous pouvez demander au Runtime Java:

public class MaxMemory {
    public static void main(String[] args) {
        Runtime rt = Runtime.getRuntime();
        long totalMem = rt.totalMemory();
        long maxMem = rt.maxMemory();
        long freeMem = rt.freeMemory();
        double megs = 1048576.0;

        System.out.println ("Total Memory: " + totalMem + " (" + (totalMem/megs) + " MiB)");
        System.out.println ("Max Memory:   " + maxMem + " (" + (maxMem/megs) + " MiB)");
        System.out.println ("Free Memory:  " + freeMem + " (" + (freeMem/megs) + " MiB)");
    }
}

Cela rapportera la "Mémoire maximale" en fonction de l'allocation de tas par défaut. Si vous avez encore besoin de jouer avec -Xmx (sur HotSpot). J'ai trouvé que fonctionnant sur Windows 7 Enterprise 64 bits, ma JVM HotSpot32 bits peut allouer jusqu'à 1577 Mo:

[C:scratch]> java -Xmx1600M MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
[C:scratch]> java -Xmx1590M MaxMemory
Total Memory: 2031616 (1.9375 MiB)
Max Memory:   1654456320 (1577.8125 MiB)
Free Memory:  1840872 (1.75559234619 MiB)
[C:scratch]>

Alors qu'avec un64 bits JVM sur le même système d'exploitation, bien sûr, c'est beaucoup plus élevé (environ 3TiB)

[C:scratch]> java -Xmx3560G MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
[C:scratch]> java -Xmx3550G MaxMemory
Total Memory: 94240768 (89.875 MiB)
Max Memory:   3388252028928 (3184151.84297 MiB)
Free Memory:  93747752 (89.4048233032 MiB)
[C:scratch]>

Comme d'autres l'ont déjà mentionné, cela dépend de la OS.

  • Pour Windows 32 bits: ce sera Le livre interne de Windows dit 2 Go pour les processus utilisateur)
  • Pour BSD / Linux 32 bits: Il est possible d'utiliser le même format que Mac OS X pour les versions 32 bits de macOS X: interne de Mac OS X book)
  • Pas sûr de Solaris 32 bits, essayez le code ci-dessus et faites-le nous savoir.

Pour un système d'exploitation hôte 64 bits, si la JVM est 32 bits, cela dépendra toujours, très probablement comme ci-dessus démontrer.

-- mise à JOUR 20110905: - je voulais juste souligner quelques autres observations / détails:

  • Le matériel sur lequel je l'ai exécuté était 64 bits avec 6 Go de RAM réelle installée. Le système d'exploitation était Windows 7 Enterprise, 64 bits
  • La quantité réelle de Runtime.MaxMemoryqui peut être allouée dépend également de l'ensemble de travail du système d'exploitation. Une fois, j'ai couru cela alors que j'avais aussi VirtualBox en cours d'exécution et j'ai trouvé que je pouvais pas avec succès démarrez la JVM HotSpot avec -Xmx1590M et a dû devenir plus petit. Cela implique également que vous pouvez obtenir plus de 1590M en fonction de la taille de votre ensemble de travail à l'époque (bien que je maintienne toujours qu'il sera sous 2GiB pour 32 bits à cause de la conception de Windows)
 80
Author: mike, 2015-04-13 11:38:03

Vous ne spécifiez pas quel OS.

Sous Windows (pour mon application - une application de gestion des risques de longue durée), nous avons observé que nous ne pouvions pas aller plus loin que 1280 Mo sur Windows 32 bits. Je doute que l'exécution d'une JVM 32 bits sous 64 bits fasse une différence.

Nous avons porté l'application sur Linux et nous exécutons une JVM 32 bits sur du matériel 64 bits et avons eu une machine virtuelle de 2,2 Go fonctionnant assez facilement.

Le plus gros problème que vous pourriez avoir est GC en fonction de ce que vous utilisez mémoire pour.

 16
Author: Fortyrunner, 2009-09-16 19:03:12

À Partir De 4.1.2 Tas De Dimensionnement:

" Pour un modèle de processus 32 bits, la taille d'adresse virtuelle maximale le processus est généralement de 4 Go, bien que certains systèmes d'exploitation limitent cela à 2 Go ou 3 Go. La taille maximale du tas est généralement de-Xmx3800m (1600m) pour 2 Go), bien que la limitation réelle dépend de l'application. Pour les modèles de processus 64 bits, le maximum est essentiellement illimité."

Trouvé une assez bonne réponse ici: Java mémoire maximale sur Windows XP .

 13
Author: djangofan, 2017-05-23 12:26:27

Nous avons récemment eu une certaine expérience avec cela. Nous avons récemment porté de Solaris (x86-64 Version 5.10) vers Linux (RedHat x86-64) et nous avons réalisé que nous avons moins de mémoire disponible pour un processus JVM 32 bits sur Linux que Solaris.

Pour Solaris, cela revient presque à 4 Go (http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit).

Nous avons exécuté notre application avec -Xms2560m-Xmx2560m-XX:MaxPermSize=512m-XX:PermSize=512m sans aucun problème sur Solaris pour les deux dernières années. J'ai essayé de le déplacer vers linux et nous avons eu des problèmes avec des erreurs aléatoires de mémoire au démarrage. Nous ne pouvions que le faire démarrer systématiquement sur -Xms2300-Xmx2300. Ensuite, nous avons été informés de ce soutien.

Un processus 32 bits sur Linux a un espace adressable maximal de 3gb (3072mb) alors que sur Solaris il est le plein 4gb (4096mb).

 12
Author: chinto, 2012-10-29 04:31:48

Les limitations d'une JVM 32 bits sur un système d'exploitation 64 bits seront exactement les mêmes que celles d'une JVM 32 bits sur un système d'exploitation 32 bits. Après tout, la JVM 32 bits s'exécutera sur une machine virtuelle 32 bits (au sens de la virtualisation), elle ne saura donc pas qu'elle fonctionne sur un système d'exploitation/machine 64 bits.

Le seul avantage à exécuter une JVM 32 bits sur un système d'exploitation 64 bits par rapport à un système d'exploitation 32 bits est que vous pouvez avoir plus de mémoire physique et que vous rencontrerez donc moins fréquemment des échanges/pagination. Cet avantage est seulement vraiment pleinement réalisé lorsque vous avez plusieurs processus, cependant.

 9
Author: Laurence Gonsalves, 2009-09-16 19:02:05

Quant à la raison pour laquelle une JVM 32 bits est utilisée au lieu d'une JVM 64 bits, la raison n'est pas technique mais plutôt administrative/bureaucratique ...

Quand je travaillais pour BEA, nous avons constaté que l'application moyenne en fait ran slower dans une JVM 64 bits, il l'a fait lors de l'exécution dans une JVM 32 bits. Dans certains cas, la performance était aussi élevée que 25% plus lente. Donc, à moins que votre application ait vraiment besoin de toute cette mémoire supplémentaire, vous feriez mieux de configurer plus de 32 bits serveur.

Si je me souviens bien, les trois justifications techniques les plus courantes pour l'utilisation d'un 64 bits que le personnel des services professionnels BEA a rencontré étaient:

  1. L'application manipulait plusieurs images massives,
  2. L'application faisait un crissement de nombre massif,
  3. L'application avait une fuite de mémoire, le client était le premier sur un contrat du gouvernement, et ils ne voulaient pas prendre le temps et le frais de traquer la fuite de mémoire. (À l'aide d'un massif de la mémoire heap augmenterait le MTBF et le prime serait toujours payé)

.

 6
Author: user1564349, 2013-03-15 19:13:08

La JVM JROCKIT actuellement détenue par Oracle prend en charge l'utilisation du tas non contigu, permettant ainsi à la JVM 32 bits d'accéder à plus de 3,8 Go de mémoire lorsque la JVM s'exécute sur un système d'exploitation Windows 64 bits. (2,8 Go lors de l'exécution sur un système d'exploitation 32 bits).

Http://blogs.oracle.com/jrockit/entry/how_to_get_almost_3_gb_heap_on_windows

La JVM peut être téléchargée librement (inscription requise) à

Http://www.oracle.com/technetwork/middleware/jrockit/downloads/index.html

 4
Author: Dale, 2011-12-11 10:23:55

Voici quelques tests sous Solaris et Linux 64 bits

Machine Solaris 10 - SPARC - T5220 avec 32 Go de RAM (et environ 9 Go gratuits)

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3750m MaxMemory
Error occurred during initialization of VM
Could not reserve space for ObjectStartArray
$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3700m MaxMemory
Total Memory: 518520832 (494.5 MiB)
Max Memory:   3451912192 (3292.0 MiB)
Free Memory:  515815488 (491.91998291015625 MiB)
Current PID is: 28274
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_30"
Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
Java HotSpot(TM) Server VM (build 20.5-b03, mixed mode)

$ which java
/usr/bin/java
$ file /usr/bin/java
/usr/bin/java: ELF 32-bit MSB executable SPARC Version 1, dynamically linked, not stripped, no debugging information available

$ prstat -p 28274
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
28274 user1     670M   32M sleep   59    0   0:00:00 0.0% java/35

BTW: Apparemment, Java n'alloue pas beaucoup de mémoire réelle au démarrage. Il semblait ne prendre qu'environ 100 Mo par instance démarrée (j'ai commencé 10)

Solaris 10 - x86-VMware VM avec 8 Go de RAM (environ 3 Go gratuits*)

La RAM libre de 3 Go n'est pas vraiment vraie. Il y a un gros morceau de RAM que les caches ZFS utilisent, mais je n'ai pas accès root pour vérifier combien exactement

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3650m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3600m MaxMemory
Total Memory: 516423680 (492.5 MiB)
Max Memory:   3355443200 (3200.0 MiB)
Free Memory:  513718336 (489.91998291015625 MiB)
Current PID is: 26841
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_41"
Java(TM) SE Runtime Environment (build 1.6.0_41-b02)
Java HotSpot(TM) Server VM (build 20.14-b01, mixed mode)

$ which java
/usr/bin/java

$ file /usr/bin/java
/usr/bin/java:  ELF 32-bit LSB executable 80386 Version 1 [FPU], dynamically linked, not stripped, no debugging information available

$ prstat -p 26841
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
26841 user1     665M   22M sleep   59    0   0:00:00 0.0% java/12

RedHat 5.5 - x86-VMware VM avec 4 Go de RAM (environ 3,8 Go utilisés - 200 Mo dans les tampons et 3,1 Go dans les caches, donc environ 3 Go gratuits)

$ alias java='$HOME/jre/jre1.6.0_34/bin/java'

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3500m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3450m MaxMemory
Total Memory: 514523136 (490.6875 MiB)
Max Memory:   3215654912 (3066.6875 MiB)
Free Memory:  511838768 (488.1274871826172 MiB)
Current PID is: 21879
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_34"
Java(TM) SE Runtime Environment (build 1.6.0_34-b04)
Java HotSpot(TM) Server VM (build 20.9-b04, mixed mode)

$ file $HOME/jre/jre1.6.0_34/bin/java
/home/user1/jre/jre1.6.0_34/bin/java: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped

$ cat /proc/21879/status | grep ^Vm
VmPeak:  3882796 kB
VmSize:  3882796 kB
VmLck:         0 kB
VmHWM:     12520 kB
VmRSS:     12520 kB
VmData:  3867424 kB
VmStk:        88 kB
VmExe:        40 kB
VmLib:     14804 kB
VmPTE:        96 kB

Même machine utilisant JRE 7

$ alias java='$HOME/jre/jre1.7.0_21/bin/java'

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3500m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3450m MaxMemory
Total Memory: 514523136 (490.6875 MiB)
Max Memory:   3215654912 (3066.6875 MiB)
Free Memory:  511838672 (488.1273956298828 MiB)
Current PID is: 23026
Waiting for user to press Enter to finish ...

$ java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) Server VM (build 23.21-b01, mixed mode)

$ file $HOME/jre/jre1.7.0_21/bin/java
/home/user1/jre/jre1.7.0_21/bin/java: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

$ cat /proc/23026/status | grep ^Vm
VmPeak:  4040288 kB
VmSize:  4040288 kB
VmLck:         0 kB
VmHWM:     13468 kB
VmRSS:     13468 kB
VmData:  4024800 kB
VmStk:        88 kB
VmExe:         4 kB
VmLib:     10044 kB
VmPTE:       112 kB
 4
Author: ih.ng, 2013-05-03 20:43:51

Devrait être beaucoup mieux

Pour une JVM 32 bits s'exécutant sur un hôte 64 bits, j'imagine que ce qui reste pour le tas sera l'espace virtuel non fragmenté disponible après la JVM, ses propres DLL et tout élément de compatibilité OS 32 bits a été chargé. Comme une supposition sauvage, je pense que 3GB devrait être possible, mais combien mieux cela dépend de la façon dont vous faites dans 32-bit-host-land.

De plus, même si vous pouviez faire un tas géant de 3 Go, vous ne voudrez peut-être pas, car cela le fera faire en sorte que les pauses GC deviennent potentiellement gênantes. Certaines personnes exécutent simplement plus de JVM pour utiliser la mémoire supplémentaire plutôt qu'une géante. J'imagine qu'ils ajustent la JVM en ce moment pour mieux fonctionner avec des tas géants.

Il est un peu difficile de savoir exactement à quel point vous pouvez faire mieux. Je suppose que votre situation 32 bits peut être facilement déterminée par expérience. Il est certainement difficile de prédire abstraitement, car beaucoup de choses en tiennent compte, en particulier parce que l'espace virtuel disponible sur 32 bits hôtes est plutôt limitée.. Le tas doit exister dans une mémoire virtuelle contiguë, donc la fragmentation de l'espace d'adressage pour les dll et l'utilisation interne de l'espace d'adressage par le noyau du système d'exploitation détermineront la plage d'allocations possibles.

Le système d'exploitation utilisera une partie de l'espace d'adressage pour mapper les périphériques HW et ses propres allocations dynamiques. Bien que cette mémoire ne soit pas mappée dans l'espace d'adressage du processus java, le noyau du système d'exploitation ne peut pas y accéder et votre espace d'adressage en même temps, donc cela limitera la taille de l'espace virtuel de tout programme.

Le chargement des DLL dépend de l'implémentation et de la publication de la JVM. Le chargement du noyau de système d'exploitation dépend d'un grand nombre de choses, la libération, la HW, combien de choses il a mappé depuis le dernier redémarrage, qui sait...

En résumé

Je parie que vous obtenez 1-2 Go en 32 bits, et environ 3 en 64 bits, donc une amélioration globale d'environ 2x.

 3
Author: DigitalRoss, 2009-09-16 19:48:04

Sur Solaris, la limite est d'environ 3,5 Go depuis Solaris 2.5. (il y a environ 10 ans)

 2
Author: Peter Lawrey, 2009-12-02 06:51:24

J'avais les mêmes problèmes avec la JVM que l'éditeur App Inventor for Android Blocks utilise. Il définit le tas à 925m max. Ce n'est pas suffisant mais je ne pouvais pas le régler plus d'environ 1200m, en fonction de divers facteurs aléatoires sur ma machine.

J'ai téléchargé Nightly, le navigateur bêta 64 bits de Firefox, et aussi la version JAVA 7 64 bits.

Je n'ai pas encore trouvé ma nouvelle limite de tas, mais je viens d'ouvrir une JVM avec une taille de tas de 5900m. Pas de problème!

Je suis en cours d'exécution Gagnez 7 64 bits Ultimate sur une machine avec 24 go de RAM.

 1
Author: user1652651, 2012-10-02 09:43:50

J'ai essayé de définir la taille du tas jusqu'à 2200M sur une machine Linux 32 bits et JVM a bien fonctionné. La JVM n'a pas démarré lorsque je l'ai définie sur 2300M.

 0
Author: Priya, 2009-10-10 01:12:45

Un point de plus ici pour la JVM 32 bits hotspot:- la capacité du tas natif = 4 Gig – Java Heap-PermGen;

Cela peut devenir particulièrement délicat pour la JVM 32 bits car le tas Java et le tas natif sont dans une course. Le plus votre tas Java est grand, plus le tas natif est petit. Tentative de configuration d'un grand tas pour une machine virtuelle 32 bits e.g .2,5 Go + augmente le risque d'erreur OutOfMemoryError native en fonction de l'empreinte de vos applications, nombre de Threads etc.

 0
Author: ajay29, 2015-02-05 18:50:06

4 go théoriques, mais en pratique (pour IBM JVM):

Le serveur d'applications Websphere 8.5.5 de Win 2k8 64, IBM 32bit

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.

Il s'agit d'un serveur d'applications Websphere 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.

 -1
Author: pk.shulgin, 2016-11-24 17:55:29