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

la question ne porte pas sur la taille maximale d'un tas sur un OS 32 bits, étant donné que les os 32 bits ont une taille de mémoire adressable maximale de 4 Go, et que la taille max heap de la JVM dépend de combien de mémoire libre contiguë peut être réservée.

je suis plus intéressé par la connaissance de la taille maximale (à la fois théorique et pratiquement réalisable) pour une JVM 32 bits tournant dans un OS 64 bits. Fondamentalement, je regarde des réponses similaires à les chiffres dans un rapport question sur DONC .

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-il est probablement trop tard pour installer une JVM 64 bits dans l'environnement de production.

97
demandé sur Community 2009-09-16 22:44:51

16 réponses

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

si vous vous attendez à atteindre cette limite, vous devriez fortement envisager de commencer une piste parallèle validant un JVM 64 bits pour votre environnement de production, donc vous avez ce prêt pour quand l'environnement 32 bits tombe en panne. Sinon, vous devrez le faire travailler sous pression, ce qui n'est jamais agréable.


Edit 2014-05-15: Oracle FAQ:

la limite théorique maximale du tas pour la JVM à 32 bits est de 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 VM les frais généraux, dans la pratique, la limite peut être beaucoup plus faible. Sur la plupart des systèmes modernes de fenêtres 32 bits, la taille maximale des tas varie de 1,4 G à 1,6 G. sur les noyaux Solaris 32 bits, l'espace d'adresse est limité à 2g. Sur les systèmes d'exploitation 64 bits utilisant la VM 32 bits, la taille max 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
répondu Thorbjørn Ravn Andersen 2017-08-04 10:36:43

vous pouvez demander au Java Runtime:

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)");
    }
}

indique la "mémoire Max" basée sur l'allocation par défaut du tas. Vous devez donc toujours jouer avec -Xmx (sur HotSpot ). J'ai trouvé que l'exécution sur Windows 7 Entreprise 64-bit, mon 32-bit HotSpot JVM peut allouer jusqu'à 1577MiB:

[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]>

considérant qu'avec une 64-bit JVM sur le même OS, bien sûr, il 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 L'OS.

  • Pour la version 32 bits de Windows: <2 go de ram ( Windows internals livre , dit 2 go pour les processus utilisateur)
  • Pour 32-bit BSD / Linux: <3 GO (à partir du Diable Livre)
  • For 32-bit MacOS X: <4GB (from Mac OS X internals book)
  • pas sûr de Solaris 32 bits, essayez le code ci-dessus et laissez-nous savoir.

pour un os hôte 64 bits, si le JVM est 32 bits, il dépendra encore, très probablement comme ci-dessus comme démontré.

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

  • le matériel que j'ai utilisé était 64 bits avec 6 Go de mémoire vive installer. Le système d'exploitation est Windows 7 Entreprise 64 bits
  • le montant réel de La Runtime.MaxMemory qui peut être alloué dépend aussi du système d'exploitation travail . Une fois, j'ai lancé ceci alors que J'avais aussi lancé VirtualBox et j'ai trouvé que je pouvais et non démarrer avec succès le HotSpot JVM avec -Xmx1590M et que je devais faire plus petit. Cela implique également que vous pouvez obtenir plus de 1590M en fonction de votre taille d'ensemble de travail à l'époque (bien que je maintienne encore qu'il sera sous 2GiB pour 32-bit en raison de la conception de Windows)
80
répondu mike 2015-04-13 11:38:03

vous ne spécifiez pas quel OS.

sous Windows (for my application - a long running risk management application) nous avons observé que nous ne pouvions pas aller plus loin que 1280MO sous Windows 32bit. Je doute que l'exécution d'une JVM de 32 bits en dessous de 64 bits fasse une différence.

nous avons porté L'application sur Linux et nous exécutons une JVM de 32 bits sur du matériel 64bit et avons eu une VM de 2,2 Go qui tourne assez facilement.

le le plus gros problème que vous pouvez avoir est GC selon ce que vous utilisez la mémoire pour.

16
répondu Fortyrunner 2009-09-16 19:03:12

De 4.1.2 Calibrage :

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

trouvé une réponse assez bonne ici: Java maximum memory sur Windows XP .

13
répondu djangofan 2017-05-23 12:26:27

Nous avons récemment eu une certaine expérience avec ce. Nous avons porté de Solaris (x86-64 Version 5.10) à Linux (RedHat x86-64) récemment et 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 lancé notre application avec - Xms2560m -Xmx2560m-XX: MaxPermSize=512m - XX: PermSize=512m sans aucun problème sur Solaris depuis quelques années. J'ai essayé de le déplacer vers linux et nous avions des problèmes avec des erreurs aléatoires de mémoire au démarrage. Nous n'avons pu le faire démarrer que sur -Xms2300-Xmx2300 . Nous en avons été informés par support.

un processus 32 bits sur Linux a un adresse maximum adressable espace de 3 Go (3072 Mo) alors que sur Solaris il est la totale de 4 go (4096 mo).

12
répondu chinto 2012-10-29 04:31:48

les limitations d'une JVM 32 bits sur un OS 64 bits seront exactement les mêmes que celles d'une JVM 32 bits sur un OS 32 bits. Après tout, le JVM 32 bits fonctionnera sur une machine virtuelle 32 bits (dans le sens de la virtualisation), donc il ne saura pas qu'il fonctionne sur une machine OS/machine 64 bits.

le seul avantage d'exécuter un JVM 32 bits sur un OS 64 bits par rapport à un OS 32 bits est que vous pouvez avoir plus de mémoire physique, et donc rencontrer des échanges/pagination moins fréquemment. Cet avantage n'est pleinement réalisée que lorsque vous avez plusieurs processus, cependant.

9
répondu Laurence Gonsalves 2009-09-16 19:02:05

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

quand je travaillais pour BEA, nous avons trouvé que l'application Moyenne en fait allait plus lentement dans une JVM 64 bits, puis il a fait quand courant dans une JVM 32 bits. Dans certains cas, le coup de performance a été jusqu'à 25% plus lent. Donc, sauf si votre demande vraiment besoin de toute cette mémoire supplémentaire, vous étiez mieux de mettre en place plus de serveurs 32 bits.

si je me souviens bien, les trois justifications techniques les plus courantes pour utiliser un 64 bits que le personnel de BEA professional services a rencontrées étaient:

  1. La demande a été la manipulation de plusieurs massive des images,
  2. faisait L'application massive de nombreux calculs,
  3. l'application avait une fuite de mémoire, le client était le premier sur un contrat avec le gouvernement, et ils ne veulent pas prendre le temps et la frais de retracer la fuite de mémoire. (En utilisant une mémoire massive heap augmenterait le MTBF et le prime serait encore payé)

.

6
répondu user1564349 2013-03-15 19:13:08

le JVM de JROCKIT actuellement détenu par Oracle prend en charge l'usage non contigu de tas, permettant ainsi à la JVM 32 bits d'accéder à plus de 3,8 Go de mémoire lorsque la JVM tourne sur un OS Windows 64 bits. (2.8 GO quand on tourne sur un OS 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 gratuitement (inscription requise) au

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

4
répondu Dale 2011-12-11 10:23:55

Voici quelques tests sous Solaris et Linux 64 bits

Solaris 10-SPARC-T5220 machine avec 32 Go de RAM (et environ 9 Go libre)

$ 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 avec le démarrage. Il semblait ne prendre qu'environ 100 Mo par instance commencée (j'ai commencé 10)

Solaris 10-x86-VMWare VM with 8 GB RAM (about 3 GB free*)

la RAM libre de 3 Go N'est pas vraiment vrai. 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 libre)

$ 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
répondu ih.ng 2013-05-03 20:43:51

devrait être beaucoup mieux

pour un JVM 32 bits tournant sur un hôte 64 bits, j'imagine que ce qui reste pour le tas sera n'importe quel espace virtuel non fragmenté disponible après le JVM, c'est sa propre DLL, et n'importe quelle compatibilité OS 32 bits a été chargée. Comme une supposition sauvage, je pense que 3 Go devrait être possible, mais combien mieux cela est dépend de la façon dont vous faites dans 32-bit-hôte-land.

aussi, même si vous pouvez faire un géant 3GB heap, vous pourriez ne pas vouloir, car cela va provoquer des pauses GC à devenir potentiellement gênant. Certaines personnes utilisent plus de JVM pour utiliser la mémoire supplémentaire plutôt qu'une mémoire géante. J'imagine qu'ils sont en train d'accorder les JVM en ce moment pour mieux travailler avec des tas Géants.

il est un peu difficile de savoir exactement combien de mieux vous pouvez faire. Je suppose que votre situation 32 bits peut être facilement déterminée par expérience. Il est certainement difficile de prédire de façon abstraite, comme beaucoup de choses entrent en elle, en particulier parce que l'espace virtuel disponible sur les hôtes 32 bits est plutôt limité.. Le tas doit exister dans une mémoire virtuelle contiguë, donc la fragmentation de l'espace d'adresse pour les dll et l'utilisation interne de l'espace d'adresse par le noyau du système d'exploitation détermineront la gamme des attributions possibles.

L'OS utilisera une partie de l'espace d'adresse pour cartographier les appareils HW et ses propres allocations dynamiques. Alors que cette mémoire n'est pas mappée dans l'adresse du processus java espace, le noyau du système D'exploitation ne peut pas y accéder et votre espace d'adresse en même temps, de sorte qu'il limitera la taille de l'espace virtuel d'un programme.

le chargement des DLL dépend de la mise en œuvre et de la libération de la JVM. Le chargement du noyau D'OS dépend d'un grand nombre de choses, la version, le HW, combien de choses il a cartographié jusqu'à présent depuis le dernier redémarrage, qui sait...

en résumé

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

3
répondu 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
répondu Peter Lawrey 2009-12-02 06:51:24

j'avais les mêmes problèmes avec la JVM que L'inventeur de L'application pour Android Blocks Editor utilise. Il place le tas à 925 m max. Ce n'est pas suffisant, mais je n'ai pas pu régler plus de 1200m, en fonction de divers facteurs aléatoires sur ma machine.

j'ai téléchargé Nightly, le navigateur beta 64-bit de Firefox, et aussi la version JAVA 7 64 bit.

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!

j'exécute Win 7 64 bit Ultimate sur une machine avec 24 Go de RAM.

1
répondu user1652651 2012-10-02 09:43:50

j'ai essayé de régler la taille du tas jusqu'à 2200M sur une machine Linux 32 bits et JVM a bien fonctionné. Le JVM n'a pas commencé quand je l'ai mis à 2300M.

0
répondu Priya 2009-10-10 01:12:45

un point de plus pour hotspot 32-bit JVM:- the native heap capacity = 4 Gig-Java Heap-PermGen;

il peut devenir particulièrement difficile pour 32-bit JVM puisque le tas de Java et natif tas sont dans une course. Le plus le volume Java est grand, plus le volume natif est petit. Essayer de configurer un grand tas pour une VM 32 bits e.g .2,5 Go + augmente le risque de OutOfMemoryError natif en fonction de votre empreinte d'application(s) , nombre de Threads etc.

0
répondu ajay29 2015-02-05 18:50:06

théorique 4 Go, mais dans la pratique (pour IBM JVM):

Win 2K8 64, IBM Websphere Application Server 8.5.5 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.

RHEL 6.4 64, IBM Websphere Application Server 8.5.5 32bit

[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
répondu pk.shulgin 2016-11-24 17:55:29