web-dev-qa-db-fra.com

Taille de segment maximale Java d'une machine virtuelle Java 32 bits sur un système d'exploitation 64 bits

La question ne concerne pas la taille de tas maximale 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 de tas maximale de la machine virtuelle dépend de la quantité de mémoire libre contiguë pouvant être réservée.

Je suis plus intéressé par la connaissance de la taille maximale (à la fois théorique et pratiquement réalisable) d'une pile JVM 32 bits s'exécutant dans un système d'exploitation 64 bits. Fondamentalement, je cherche des réponses similaires à les chiffres d'une question connexe sur SO .

En ce qui concerne l'utilisation d'une machine virtuelle 32 bits au lieu d'une version 64 bits, la raison n'est pas technique, mais plutôt administrative/bureaucratique - il est probablement trop tard pour installer une machine virtuelle Java 64 bits dans l'environnement de production.

104
Vineet Reynolds

Les machines virtuelles Java 32 bits qui s'attendent à disposer d'une seule grande quantité de mémoire et à utiliser des pointeurs bruts ne peuvent pas utiliser plus de 4 Go (puisqu'il s'agit de la limite de 32 bits qui s'applique également aux pointeurs). Cela inclut Sun et - j'en suis sûr - les implémentations IBM. Je ne sais pas si par exemple JRockit ou d'autres ont une option de mémoire étendue avec leurs implémentations 32 bits.

Si vous vous attendez à respecter cette limite, envisagez vivement de démarrer une piste parallèle validant une machine virtuelle Java 64 bits pour votre environnement de production afin de la préparer au moment où l'environnement 32 bits tombera en panne. Sinon, vous devrez faire ce travail sous pression, ce qui n’est jamais Nice.


Edit 2014-05-15: FAQ Oracle:

La limite de segment théorique maximale pour la machine virtuelle Java 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 VM, la limite peut en pratique être beaucoup plus basse. Sur la plupart des systèmes Windows 32 bits modernes, la taille maximale du segment de mémoire va de 1,4 à 1,6 Go. 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 segment de mémoire peut être plus élevée et s'approcher de la 4G sur de nombreux systèmes Solaris.

( http://www.Oracle.com/technetwork/Java/hotspotfaq-138619.html#gc_heap_32bit )

66

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 indiquera la "Mémoire Max" basée sur l'allocation de segment par défaut. Il vous faudra donc toujours jouer avec -Xmx (sur HotSpot). J'ai constaté que, sous Windows 7 Entreprise 64 bits, ma machine virtuelle Java 2 bits HotSpot peut allouer jusqu'à 1577 Mo:

 [C: scratch]> Java -Xmx1600M MaxMemory 
 Une erreur s'est produite lors de l'initialisation de la machine virtuelle 
 Impossible de réserver suffisamment d'espace pour le tas d'objet 
. Impossible de créer la machine virtuelle Java. 
 [C: scratch]> Java -Xmx1590M MaxMemory 
 Mémoire totale: 2031616 (1.9375 Mio) 
 Mémoire max .: 1654456320 (1577,8125 Mio) 
 Mémoire libre: 1840872 (1,75559234619 Mio) 
 [C: scratch]> 

Tandis qu'avec une JVM 64-bit ​​sur le même système d'exploitation, c'est beaucoup plus élevé (environ 3TiB)

 [C: scratch]> Java -Xmx3560G MaxMemory 
 Une erreur s'est produite lors de l'initialisation de la machine virtuelle 
 Impossible de réserver suffisamment d'espace pour le tas d'objet 
. [C: scratch]> Java -Xmx3550G MaxMemory 
 Mémoire totale: 94240768 (89,875 Mio) 
 Mémoire maximale: 3388252028928 (3184151.84297 Mio) 
 Mémoire libre: 93747752 (89.4048233032 MiB) 
 [C: scratch]> 

Comme d'autres l'ont déjà mentionné, cela dépend du système d'exploitation.

  • Pour Windows 32 bits: ce sera <2 Go ( livre interne de Windows indique 2 Go pour les processus utilisateur)
  • Pour BSD/Linux 32 bits: <3 Go (extrait du livre du diable)
  • Pour MacOS X 32 bits: <4 Go (à partir de composants internes de Mac OS X livre)
  • Pas sûr de Solaris 32 bits, essayez le code ci-dessus et faites-le nous savoir.

Pour un OS hôte 64 bits, si la JVM est 32 bits, cela dépendra toujours, probablement comme ci-dessus, comme indiqué.

- MISE À JOUR 20110905 : Je voulais juste signaler quelques autres observations/détails:

  • Le matériel sur lequel j’ai exécuté cette machine était de 64 bits avec 6 Go de RAM réelle installée. Le système d'exploitation était Windows 7 Entreprise, 64 bits
  • La quantité réelle de Runtime.MaxMemory pouvant être allouée dépend également du système d'exploitation jeu de travail. Une fois, j’ai exécuté cela alors que VirtualBox était également en cours d’exécution et j’ai trouvé que je pouvais pas démarrer correctement la machine virtuelle HotSpot avec -Xmx1590M et que je devais réduire la taille. Cela implique également que vous pouvez obtenir plus de 1590M en fonction de la taille de votre jeu de travail à ce moment-là (bien que je maintienne toujours qu'il sera inférieur à 2 Go pour 32 bits en raison de la conception de Windows).
85
mike

Vous ne spécifiez pas qui OS.

Sous Windows (pour mon application - une application de gestion des risques de longue date), nous avons constaté que nous ne pouvions pas aller plus loin que 1280 Mo sous Windows 32 bits. Je doute que faire fonctionner une machine virtuelle Java 32 bits sous 64 bits fasse une différence.

Nous avons porté l'application sur Linux et nous utilisons une machine virtuelle Java 32 bits sur du matériel 64 bits. Notre VM 2.2GB a fonctionné assez facilement.

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

16
Fortyrunner

De 4.1.2 Dimensionnement de tas :

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

Vous avez trouvé une très bonne réponse ici: mémoire maximale Java sous Windows XP .

14
djangofan

Nous avons récemment eu une certaine expérience avec cela. Nous avons récemment transféré de Solaris (x86-64 version 5.10) à Linux (RedHat x86-64) et avons constaté que nous disposions de moins de mémoire pour un processus JVM 32 bits sous Linux que Solaris.

Pour Solaris, cela équivaut 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 sous Solaris au cours des dernières années. Essayé de le déplacer vers Linux et nous avons eu des problèmes avec des erreurs aléatoires de mémoire insuffisante au démarrage. Nous ne pouvions que le faire démarrer systématiquement sur - - Xms2300 -Xmx23. Ensuite, nous avons été informés par support.

Un processus 32 bits sous Linux a un espace d'adressage adressable maximal de 3 Go (3072 Mo), tandis que sur Solaris, il s'agit de 4 Go (4096 Mo) complets.

12
chinto

Les limitations d'une machine virtuelle Java 32 bits sur un système d'exploitation 64 bits seront exactement les mêmes que celles d'une machine virtuelle Java 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), de sorte qu'elle ne saura pas qu'elle s'exécute sur un système d'exploitation/machine 64 bits.

L’avantage d’exécuter une machine virtuelle Java 32 bits sur un système d’exploitation 64 bits par rapport à un système d'exploitation 32 bits est que vous pouvez disposer de plus de mémoire physique et que, par conséquent, la permutation/la pagination est moins fréquente. Cependant, cet avantage n’est réellement pleinement réalisé que lorsque vous avez plusieurs processus.

9
Laurence Gonsalves

Pourquoi utiliser une machine virtuelle 32 bits au lieu d’une machine 64 bits? La raison n’est pas technique, mais plutôt administrative/bureaucratique ...

Lorsque je travaillais pour BEA, nous avons constaté que l’application moyenne fonctionnait plus lentement dans une JVM 64 bits, puis a fait lors de l'exécution dans une JVM 32 bits. Dans certains cas, les performances ont été ralenties de 25%. Ainsi, à moins que votre application ait réellement besoin de toute cette mémoire supplémentaire, il est préférable de configurer davantage de serveurs 32 bits.

Si je me souviens bien, voici les trois justifications techniques les plus courantes de l'utilisation d'un logiciel 64 bits par le personnel des services professionnels de BEA:

  1. L'application manipulait plusieurs images massives,
  2. L’application faisait des calculs énormes,
  3. L’application avait une fuite de mémoire, le client était le plus important sur un contrat gouvernemental et ils ne voulaient pas prendre le temps et les dépenses nécessaires pour localiser la fuite de mémoire. (L'utilisation d'un tas de mémoire massif augmenterait le MTBF et le taux préférentiel serait toujours payé)

.

6
user1564349

Voici quelques tests sous Solaris et Linux 64 bits

Solaris 10 - SPARC - Ordinateur T5220 avec 32 Go RAM (et environ 9 Go disponibles)

$ 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 au démarrage. Cela semblait prendre environ 100 Mo par instance (j'ai commencé 10)

Solaris 10 - x86 - VMWare VM avec 8 Go RAM (environ 3 Go disponibles *)

Les 3 Go libres RAM ne sont pas vraiment vrais. Il y a une grande quantité de RAM que les caches ZFS utilisent, mais je n'ai pas accès à la racine 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 RAM (environ 3,8 Go utilisés - 200 Mo en mémoire tampon et 3,1 Go en mémoire cache, soit environ 3 Go d'espace 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 avec 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
ih.ng

La machine virtuelle JROCKIT appartenant actuellement à Oracle prend en charge l'utilisation de segments de mémoire non contigus, permettant ainsi à la machine virtuelle 32 bits d'accéder à plus de 3,8 Go de mémoire lorsque celle-ci 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 gratuitement (inscription requise) à l'adresse

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

4
Dale

Devrait être beaucoup mieux

Pour une machine virtuelle Java 32 bits s'exécutant sur un hôte 64 bits, j'imagine que ce qui restera pour le segment de mémoire correspondra à tout espace virtuel non fragmenté disponible après le chargement de la machine virtuelle Java, de sa propre DLL et de tout élément de compatibilité de système d'exploitation 32 bits. En toute logique, je pense que 3 Go devrait être possible, mais son efficacité dépend de vos performances en 32-bit-Host-Land.

En outre, même si vous pouviez créer un segment de mémoire gigantesque de 3 Go, vous ne voudriez peut-être pas le faire, car les pauses du GC pourraient devenir potentiellement gênantes. Certaines personnes utilisent simplement plus de machines virtuelles pour utiliser la mémoire supplémentaire plutôt qu'une mémoire géante. J'imagine qu'ils adaptent actuellement la machine virtuelle pour qu'ils fonctionnent mieux avec des tas gigantesques.

Il est un peu difficile de savoir exactement ce que vous pouvez faire de mieux. Je suppose que votre situation 32 bits peut être facilement déterminée par expérience. Il est certes difficile de prédire de manière abstraite, car de nombreux facteurs entrent en ligne de compte, notamment parce que l’espace virtuel disponible sur les hôtes 32 bits est plutôt contraint. Le segment de mémoire doit exister dans la mémoire virtuelle contiguë. Par conséquent, la fragmentation de 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 matériels et ses propres allocations dynamiques. Bien que cette mémoire ne soit pas mappée dans l'espace adresse de processus Java, le noyau du système d'exploitation ne peut pas y accéder simultanément et accéder à votre espace adresse. Il limitera donc la taille de l'espace virtuel d'un programme.

Le chargement des DLL dépend de la mise en oeuvre et de la publication de la machine virtuelle Java. Le chargement du noyau du système d'exploitation dépend d'un grand nombre d'éléments, la version, le matériel, le nombre d'éléments qu'il a mappés jusqu'à maintenant depuis le dernier redémarrage, qui sait ...

En résumé

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

3
DigitalRoss

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

2
Peter Lawrey

J'avais les mêmes problèmes avec la machine virtuelle que celui utilisé par App Inventor pour Android Blocks Editor. Il établit le tas à 925m max. Cela ne suffit pas, mais je ne peux pas régler plus de 1200 m, en fonction de divers facteurs aléatoires sur ma machine.

J'ai téléchargé Nightly, le navigateur bêta 64 bits de Firefox, ainsi que Java 7 version 64 bits.

Je n'ai pas encore trouvé ma nouvelle limite de segment de mémoire, mais je viens d'ouvrir une machine virtuelle Java avec une taille de segment de mémoire de 5900m. Aucun problème!

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

1
user1652651

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
Priya

un point supplémentaire ici pour la machine virtuelle Java 32 bits: - la capacité de segment de mémoire native = 4 Go - Java Heap - PermGen;

Cela peut s'avérer particulièrement difficile pour les JVM 32 bits puisque le Java Heap et le Heap natif sont dans une course. Plus votre Java Heap est gros, plus le tas natif est petit. Tenter de configurer un segment de mémoire volumineux pour une mémoire 32 bits VM, par exemple plus de 2,5 Go, augmente le risque d'erreur OutOfMemoryError en fonction de l'encombrement de votre/vos application (s), du nombre de threads, etc.

0
ajay29
0
Felipe Buccioni