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

107

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ë qui peut être réservée.

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

Quant à savoir pourquoi 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.

Vineet Reynolds
la source

Réponses:

70

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 (car c'est la limite de 32 bits qui s'applique également aux pointeurs). Cela inclut Sun et - j'en suis presque sûr - également les 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 afin que vous ayez cela prêt pour quand l'environnement 32 bits tombe en panne. Sinon, vous devrez faire ce travail sous pression, ce qui n'est jamais agréable.


Modifier le 15/05/2014: FAQ Oracle:

La limite de tas théorique maximale 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 de la VM, en pratique, la limite peut être beaucoup plus faible. Sur la plupart des systèmes Windows 32 bits modernes, la taille maximale du tas varie de 1,4G à 1,6G. 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 )

Thorbjørn Ravn Andersen
la source
Aucune pression de travail ici. Je sais qu'une JVM 64 bits aurait dû être installée en premier lieu. Mais cela m'a fait réfléchir à la façon dont une JVM 32 bits fonctionnerait dans un environnement avec plus de ressources à sa disposition.
Vineet Reynolds
1
N'est-ce pas environ 2 Go à cause des signatures? Ou est-ce juste la JVM Sun?
Sebastian Ganslandt
9
Les pointeurs ne sont pas signés - cela n'a pas de sens de parler d'emplacements mémoire négatifs.
Thorbjørn Ravn Andersen
12
Non, ce n'est pas 2 Go à cause de la signature. Cependant, une partie de l'espace d'adressage de 4 Go est réservée au noyau du système d'exploitation. Sur les versions grand public normales de Windows, la limite est de 2 Go. Sur les versions Linux et serveur de Windows (32 bits), la limite est de 3 Go par processus.
Jesper
3
@Jesper Je me demandais si une JVM 32 bits fonctionnant sur un système d'exploitation 64 bits pourrait avoir un espace d'adressage complet de 4 Go disponible?
Thorbjørn Ravn Andersen
90

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

Cela indiquera la «mémoire maximale» basée sur l'allocation de tas par défaut. Vous auriez donc toujours besoin de jouer avec -Xmx(sur HotSpot ). J'ai constaté que fonctionnant sous Windows 7 Entreprise 64 bits, ma JVM HotSpot 32 bits peut allouer jusqu'à 1577 Mo:

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

Alors qu'avec une JVM 64 bits sur le même OS, bien sûr, c'est beaucoup plus élevé (environ 3 To)

[C: scratch]> java -Xmx3560G MaxMemory
Une erreur s'est produite lors de l'initialisation de la VM
Impossible de réserver suffisamment d'espace pour le tas d'objets
[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 Mio)
[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 ( le livre interne de Windows indique 2 Go pour les processus utilisateur)
  • Pour BSD / Linux 32 bits: <3 Go (tiré du Devil Book)
  • Pour MacOS X 32 bits: <4 Go (à partir du livre interne de Mac OS X )
  • Vous n'êtes 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, comme illustré.

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

  • Le matériel sur lequel j'ai exécuté ceci était de 64 bits avec 6 Go de RAM réelle installée. Le système d'exploitation était Windows 7 Entreprise, 64 bits
  • Le montant réel Runtime.MaxMemoryqui peut être alloué dépend également de l'ensemble de travail du système d' exploitation . Une fois, j'ai couru cela alors que VirtualBox était également en cours d'exécution et j'ai constaté que je ne pouvais pas démarrer avec succès la JVM HotSpot et que je -Xmx1590Mdevais devenir plus petit. Cela implique également que vous pouvez obtenir plus de 1590 Mo en fonction de la taille de votre ensemble de travail à l'époque (même si je maintiens toujours que ce sera moins de 2 Go pour 32 bits en raison de la conception de Windows)
Mike
la source
13
J'aime le fait que vous ayez testé plutôt que fait des suppositions.
Jim Hurne
3
@djangofan a raison. Le programme doit être divisé par 1 048 576 (1 024 * 1 024, ou 2 ^ 20), et non par 104 856. Mais, c'est juste une chose d'affichage. Comme vous pouvez le voir dans la commande, il a seulement essayé de définir la taille maximale du tas à 1590 Mio.
Jim Hurne
1
Réponse très cool (je voudrais dire la réponse), avec un exemple de code et des détails couvrant tous les systèmes d'exploitation.
TGP1994
3
Suite à mon commentaire précédent: les jdocs (pour Windows au moins) spécifient que les paramètres -Xmx et -Xms doivent recevoir une valeur multiple de 1024 ... Je ne sais pas si 1590 l'est, donc je trouve étrange il faut s'attendre à des résultats.
TGP1994
4
TGP1994 bien repéré. Je pense que, parce que j'ai spécifié des multiples «M» et «G», alors la taille (en octets) fonctionnera de toute façon comme un multiple de 1024 octets. Par exemple, 1590M sera analysé en 1590 * (1024 * 1024) = 1667235840 octets (1628160KiB - un multiple pair de 1024 bien sûr).
mike
16

Vous ne spécifiez pas lequel 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 une VM de 2,2 Go fonctionnait assez facilement.

Le plus gros problème que vous pourriez avoir est GC en fonction de l'utilisation de la mémoire.

Fortyrunner
la source
Je préférerais connaître la limitation de Solaris 10, mais ce n'est que pour mon problème actuel. Je voudrais également savoir pour d'autres systèmes d'exploitation, pour un jour de pluie :)
Vineet Reynolds
Je ne suis pas sûr de Solaris. Je m'attendrais à ce que la taille de la VM soit assez grande, mon expérience de Java sur Solaris remontait à quelques années. Et être une VM Sun sur un OS Sun sur du matériel Sun - les choses fonctionnaient plutôt bien. J'ai également été amené à croire qu'il y avait moins de problèmes de GC sous Solaris que sous Linux / Windows.
Fortyrunner
Quel Windows était-ce. Je pense que les versions serveur de Windows 32 bits peuvent gérer beaucoup mieux de grandes quantités de mémoire.
Thorbjørn Ravn Andersen
Ah, enfin une mention de l'OS ;-) Vous avez un noyau 64 bits installé?
Thorbjørn Ravn Andersen
C'était un serveur Win2k. Un passage à Win2k3 (les choses bougent lentement ..) était trop tard et nous sommes passés à Linux à la place.
Fortyrunner
14

À partir de 4.1.2 Dimensionnement du 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 la limitent à 2 Go ou 3 Go. La taille maximale du segment de mémoire est généralement de -Xmx3800m (1600m) pour les limites de 2 Go. ), bien que la limitation réelle dépende de l'application. Pour les modèles de processus 64 bits, le maximum est essentiellement illimité. "

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

Djangofan
la source
12

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 avons réalisé que nous avons moins de mémoire disponible pour un processus JVM 32 bits sous 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 problème sur Solaris ces 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 insuffisante au démarrage. Nous n'avons pu le faire démarrer de manière cohérente que sur -Xms2300 -Xmx2300 . Ensuite, nous en avons été informés par le support.

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

chinto
la source
La raison de la réponse donnée par le support réside dans la quantité de mémoire adressable disponible pour un processus. Cela dépend du noyau Linux et même du matériel. Théoriquement, la mémoire adressable est limitée à 2 ^ 32 = 4G (et la taille du tas Java serait inférieure à cela). Mais cela peut (théoriquement) être étendu en utilisant hugemem et PAE; Je n'ai pas essayé cela.
Vineet Reynolds
9

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 fonctionnera sur une machine virtuelle 32 bits (dans le sens de la virtualisation) et ne saura donc pas qu'elle s'exécute sur un système d'exploitation / une 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 l'échange / la pagination. Cet avantage n'est toutefois pleinement réalisé que lorsque vous disposez de plusieurs processus.

Laurence Gonsalves
la source
1
Il peut y avoir une légère différence selon le matériel et la façon dont il est virtualisé. Une partie de l'espace adressable de 4 Go est généralement utilisée pour les périphériques mappés en mémoire. La couche de virtualisation peut avoir ou non la même empreinte mémoire que les périphériques physiques de la machine.
Eric J.
8
Pas assez. Il y a plus de place pour la JVM dans une machine 64 bits car l'espace d'adressage 32 bits n'a pas à être partagé avec le système d'exploitation ou les interfaces matérielles.
Thorbjørn Ravn Andersen
C'est vrai, mais tout cela signifie que votre machine virtuelle 32 bits peut avoir une surcharge légèrement différente de celle d'une machine réelle 32 bits (soit pire, soit meilleure). Dans tous les cas, vous exécutez la JVM sur une machine 32 bits (réelle ou virtuelle) et vous serez donc soumis aux contraintes 32 bits standard. soit: un plafond absolu de 4 Go.
Laurence Gonsalves
Thorbjørn: le système d'exploitation et les interfaces matérielles doivent encore être mappés dans la VM 32 bits. La quantité précise d'entendue peut être différente, mais elle sera toujours là. Si vous pouvez le virtualiser sous un système d'exploitation 64 bits, qu'est-ce qui vous empêche de le virtualiser sous un système d'exploitation 32 bits? C'est de la mémoire virtuelle dont nous parlons.
Laurence Gonsalves
2
LG: Je ne suis pas d'accord avec votre réponse initiale. Le noyau du système d'exploitation et tout espace d'adressage du matériel et du bus qu'il mappe grignotera beaucoup d'espace d'adressage, et bien que cela ne soit pas mappé dans le programme utilisateur, il réduit la quantité "restante" une fois que le système d'exploitation s'est installé. Il s'agit d'une quantité considérable d'un espace de 4 Go sur 32 bits. Traditionnellement, cela signifie qu'environ 25% à 75% des 4 Go ne sont pas disponibles pour les processus utilisateur. :-) kernel hacker
DigitalRoss
6

Quant à savoir pourquoi une JVM 32 bits est utilisée au lieu d'un 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 en fait plus lentement dans une JVM 64 bits, puis lors de l'exécution dans une JVM 32 bits. Dans certains cas, les performances ont été jusqu'à 25% plus lentes. Ainsi, à moins que votre application n'ait vraiment besoin de toute cette mémoire supplémentaire, vous feriez mieux de configurer plus de serveurs 32 bits.

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 du BEA a rencontrées étaient:

  1. L'application manipulait plusieurs images massives,
  2. L'application faisait des calculs massifs de nombres,
  3. L'application avait une fuite de mémoire, le client était le principal sur un contrat gouvernemental et ils ne voulaient pas prendre le temps et les frais de recherche de la fuite de mémoire. (L'utilisation d'un tas de mémoire massif augmenterait le MTBF et le prime serait toujours payé)

.

user1564349
la source
C'est bien que vous fournissiez des conseils de première main, ancien travailleur du BEA :)
emecas
4

La JVM JROCKIT actuellement détenue par Oracle prend en charge l'utilisation de 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 gratuitement (inscription requise) sur

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

Vallée
la source
4

Voici quelques tests sous Solaris et Linux 64 bits

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

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

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

La RAM libre de 3 Go n'est pas vraiment vraie. Les caches ZFS utilisent une grande partie de la RAM, mais je n'ai pas d'accès root pour vérifier la quantité exacte

$ 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 - VM VMWare 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 libres)

$ 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
ih.ng
la source
Il y a des résultats de test utiles ici pour les plates-formes qui nous manquaient. Bon travail avec l'utilisation des vidages de fichiers et de mémoire.
mike
3

Devrait être beaucoup mieux

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

De plus, même si vous pouviez créer un tas géant de 3 Go, vous ne voudrez peut-être pas le faire, car cela rendrait les pauses GC potentiellement gênantes. Certaines personnes utilisent simplement plus de JVM pour utiliser la mémoire supplémentaire plutôt qu'une seule géante. J'imagine qu'ils règlent actuellement les JVM pour mieux fonctionner avec des tas géants.

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 certainement difficile de prédire de manière abstraite, car beaucoup de choses y jouent, 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'adressage pour 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 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, ce qui limitera la taille de l'espace virtuel de tout programme.

Le chargement des DLL dépend de l'implémentation et de la version de la JVM. Le chargement du noyau du système d'exploitation dépend d'un grand nombre de choses, de la version, du matériel, du nombre de choses qu'il a mappées jusqu'à présent 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, soit une amélioration globale d'environ 2x .

DigitalRoss
la source
1
Malheureusement, je n'ai pas d'environnement 64 bits à ma disposition où je pourrais expérimenter le drapeau Xmx. Celui que je connais a une énorme (32 * n) Go de RAM disponible, mais hors limites. C'est pourquoi je voulais savoir comment une JVM 32 bits fonctionnerait sans toutes les contraintes auxquelles elle est normalement confrontée dans un monde 32 bits.
Vineet Reynolds
Eh bien, bonne question. Je suis sûr que la réponse de base est "cela fonctionnera mieux".
DigitalRoss
Ok, j'ai modifié ma réponse pour me concentrer un peu plus sur votre question réelle. :-)
DigitalRoss
1
≅ 3 Go en 64 bits semble à peu près correct. Thorbjørn avait déjà indiqué pourquoi il ne peut théoriquement pas dépasser 4 Go. Dommage que je ne puisse accepter deux réponses.
Vineet Reynolds
Si vous avez une grande boîte, vous pouvez expérimenter avec un Solaris 64 bits dans par exemple virtualbox (qui a le meilleur support d'invité Solaris).
Thorbjørn Ravn Andersen
2

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

Peter Lawrey
la source
Je vais expérimenter cela, en utilisant Oracle Solaris Express 11.
djangofan
1
@Peter Lawrey Uhm .. Solaris 2.5 était il y a près de 20 ans si vous considérez la date de sortie de mai 1996 .... bien sûr, il n'a pas EOL avant environ 2005.
cb88
1

J'avais les mêmes problèmes avec la JVM qu'utilise App Inventor pour Android Blocks Editor. Il fixe le tas à 925m max. Ce n'est pas suffisant mais je ne pouvais pas le régler à plus de 1200 m environ, 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 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 . Aucun problème!

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

user1652651
la source
0

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

Priya
la source
Je pensais ajouter que sur Windows VISTA 64 bits, une JVM 32 bits atteint un maximum de 1582 m (valeur -Xmx). Il va se plaindre si je précise 1583m. Je ne sais pas si cette valeur change d'une machine à l'autre. L'ordinateur sur lequel j'ai testé cela avait en fait 4 Go de RAM physique.
Santosh Tiwari le
@SantoshTiwari ça change de machine en machine, mais voici pourquoi
Eugene
0

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

Cela peut devenir particulièrement délicat pour la JVM 32 bits car le Java Heap et le Heap natif sont dans une course. Plus votre tas Java est grand, plus le tas natif est petit. Tenter de configurer un gros tas pour une machine virtuelle 32 bits, par exemple, 2,5 Go + augmente le risque d'OutOfMemoryError natif en fonction de l'empreinte de vos applications, du nombre de threads, etc.

ajay29
la source
0

La limitation vient également du fait que pour une 32 bitVM, heapelle - même doit commencer à l'adresse zéro si vous voulez tout cela 4GB.

Pensez-y, si vous souhaitez référencer quelque chose via:

0000....0001

c'est-à-dire: une référence qui a cette représentation de bits particulière, cela signifie que vous essayez d'accéder à la toute première mémoire à partir du tas. Pour que cela soit possible, le tas doit commencer à l'adresse zéro. Mais cela ne se produit jamais, cela commence à un certain décalage par rapport à zéro:

    | ....               .... {heap_start .... heap_end} ... |
 --> (this can't be referenced) <--

Étant donné que le tas ne commence jamais à partir de l'adresse zéro dans un OS, il y a pas mal de bits qui ne sont jamais utilisés à partir d'une 32référence de bits, et en tant que tel, le tas qui peut être référencé est inférieur.

Eugène
la source
-1

Théorique 4 Go, mais en pratique (pour IBM JVM):

Win 2k8 64, serveur d'applications IBM Websphere 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, serveur d'applications IBM 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.

pk.shulgin
la source