J'ai toujours été en mesure d'allouer 1400 mégaoctets pour Java SE fonctionnant sous Windows 32 bits XP (Java 1.4, 1.5 et 1.6).
Java -Xmx1400m ...
Aujourd'hui, j'ai essayé la même option sur une nouvelle machine Windows XP) en utilisant Java 1.5_16 et 1.6.0_07 et j'ai eu l'erreur:
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
Par essais et erreurs, il semble que 1200 mégaoctets soit le maximum que je puisse allouer sur cette machine.
Des idées pourquoi une machine permettrait 1400 et une autre seulement 1200?
Edit: La machine dispose de 4 Go de RAM avec environ 3,5 Go que Windows peut reconnaître.
N'oubliez pas que Windows dispose d'une gestion de mémoire virtuelle et que la machine virtuelle Java n'a besoin que d'une mémoire contiguë dans son espace d'adressage. Ainsi, les autres programmes exécutés sur le système ne devraient pas nécessairement avoir un impact sur la taille de votre tas. Ce qui vous gênera, ce sont les DLL qui seront chargées dans votre espace adresse. Malheureusement, les optimisations dans Windows qui minimisent le déplacement des DLL lors de la liaison augmentent les chances que vous disposiez d'un espace d'adressage fragmenté. Les éléments susceptibles de réduire votre espace adresse en dehors des tâches habituelles incluent les logiciels de sécurité, le logiciel CBT, les logiciels espions et autres formes de programmes malveillants. Les correctifs de sécurité, les versions d’exécution C, etc., sont probablement à l’origine des variances. Les pilotes de périphérique et les autres bits du noyau ont leur propre espace d’adresse (les 2 autres Go de l’espace de 4 Go à 32 bits).
Vous pouvez essayez de passer par vos liaisons DLL dans votre processus JVM et essayez de rebaser votre DLL dans un espace d'adressage plus compact. Pas amusant, mais si vous sont désespérés ...
Alternativement, vous pouvez simplement basculer vers Windows 64 bits et une JVM 64 bits. En dépit de ce que d’autres ont suggéré, bien qu’il consomme plus de RAM, vous aurez beaucoup plus d’adresses virtuelles contiguës, et allouer 2 Go de manière contiguë serait trivial.
Cela a à voir avec la mémoire contiguë.
Voici quelques informations que j'ai trouvées en ligne pour quelqu'un qui le demandait auparavant, prétendument d'un "dieu de la VM":
La raison pour laquelle nous avons besoin d'une région de mémoire contiguë pour le segment de mémoire est que nous avons un ensemble de structures de données latérales indexées par des décalages (mis à l'échelle) dès le début du segment de mémoire. Par exemple, nous suivons les mises à jour de référence d'objet avec un "tableau de marques de carte" comportant un octet pour chaque 512 octets de segment de mémoire. Lorsque nous stockons une référence dans le tas, nous devons marquer l'octet correspondant dans le tableau de marques de cartes. Nous décalons à droite l'adresse de destination du magasin et l'utilisons pour indexer le tableau de marques de carte. Des jeux d'arithmétique amusants que vous ne pouvez pas faire dans Java) (vous devez :-) jouer en C++.
Nous n’avons généralement pas de difficulté à obtenir des régions contiguës modestes (jusqu’à environ 1,5 Go sous Windohs, jusqu’à environ 3,8 Go sous Solaris. YMMV.). Sous Windohs, le problème vient principalement du fait que certaines bibliothèques chargées avant le démarrage de la machine virtuelle Java divisent l’espace adresse. L'utilisation du commutateur/3GB ne rebase pas ces bibliothèques, elles restent donc un problème pour nous.
Nous savons comment faire des tas en morceaux, mais il y aurait des frais généraux à les utiliser. Nous avons davantage de demandes pour une gestion de stockage plus rapide que pour des tas plus importants dans la JVM 32 bits. Si vous voulez vraiment de gros tas, passez à la JVM 64 bits. Nous avons toujours besoin de mémoire contiguë, mais il est beaucoup plus facile d'accéder à un espace d'adressage 64 bits.
Les limites de taille de segment Java) pour Windows sont les suivantes:
Cela ne vous aide pas à obtenir un plus gros segment Java), mais vous savez maintenant que vous ne pouvez pas aller au-delà de ces valeurs.
Oracle JRockit , qui peut gérer un segment de mémoire non contigu, peut avoir une taille de segment Java de 2,85 Go sous Windows 2003/XP avec le commutateur/3GB. Il semble cette fragmentation peut avoir un impact considérable sur la taille d'un tas Java).
La machine virtuelle Java de Sun a besoin de mémoire contiguë. La quantité maximale de mémoire disponible est donc dictée par la fragmentation de la mémoire. En particulier, les DLL du pilote ont tendance à fragmenter la mémoire lors du chargement dans une adresse de base prédéfinie. Donc, votre matériel et ses pilotes déterminent la quantité de mémoire que vous pouvez obtenir.
Deux sources pour cela avec les déclarations des ingénieurs Sun: forumblog
Peut-être une autre JVM? Avez-vous essayé Harmony ? Je pense qu'ils ont prévu d'autoriser la mémoire non continue.
La machine virtuelle Java a besoin de mémoire contiguë. En fonction de ce qui est en cours d’exécution, de ce qui était en cours d’exécution et de la manière dont Windows gère la mémoire, vous pourrez peut-être obtenir jusqu’à 1,4 Go de mémoire contiguë. Je pense que Windows 64 bits autorisera des tas plus importants.
Je pense que cela a plus à voir avec la façon dont Windows est configuré comme l'indique cette réponse: Java -Xmx Option
Quelques tests supplémentaires: j'ai pu allouer 1300 Mo sur un ancien ordinateur Windows XP avec seulement 768 Mo physique RAM (plus de la mémoire virtuelle). Sur ma machine RAM de 2 Go, je ne peux obtenir que 1220 Mo. Sur diverses autres machines de l'entreprise (avec l'ancienne version de Windows XP), j'ai pu obtenir 1400 Mo. La machine avec une limite de 1220 Mo est assez récente (elle vient d’être achetée auprès de Dell), alors peut-être qu’elle a des fenêtres et des DLL plus récentes (et plus gonflées) (elle tourne sous Windows XP Pro Version 2002 SP2).
J'ai reçu ce message d'erreur lors de l'exécution d'un programme Java à partir d'un VPS virtuozzo (à mémoire limitée). Je n'avais pas spécifié d'arguments de mémoire et j'ai trouvé qu'il était nécessaire de définir explicitement un petit le montant par défaut doit être trop élevé, par exemple -Xmx32m (doit évidemment être réglé en fonction du programme que vous exécutez).
Il suffit de mettre ceci ici au cas où quelqu'un d'autre obtiendrait le message d'erreur ci-dessus sans spécifier une grande quantité de mémoire, comme l'a fait le questionneur.
JDK/JRE de Sun nécessite une quantité de mémoire contiguë si vous allouez un bloc énorme.
Le système d'exploitation et les applications initiales ont tendance à allouer des morceaux lors du chargement, ce qui fragmente la RAM disponible. Si un bloc contigu n'est PAS disponible, le JDK de Sun ne peut pas l'utiliser. JRockit de Bea (acquis par Oracle) peut allouer de la mémoire à partir de pièces.
Tout le monde semble répondre à une question sur la mémoire contiguë, mais a négligé de reconnaître un problème plus urgent.
Même avec une allocation de mémoire contiguë à 100%, vous ne pouvez pas avoir une taille de segment de mémoire de 2 GiB sur un système d'exploitation Windows 32 bits (* par défaut). En effet, les processus Windows 32 bits ne peuvent pas traiter plus de 2 GiB d'espace.
Le processus Java contiendra perm gen (pre Java 8), taille de pile par thread, surcharge JVM/bibliothèque (qui augmente sensiblement avec chaque construction) tous en plus au tas.
De plus, les indicateurs JVM et leurs valeurs par défaut changent d'une version à l'autre. Il suffit de lancer ce qui suit et vous aurez une idée:
Java -XX:+PrintFlagsFinal
De nombreuses options affectent la division de la mémoire dans et hors du tas. Vous laissant avec plus ou moins de ce 2 GiB pour jouer avec ...
Pour réutiliser des portions de this de ma réponse (à propos de Tomcat, mais s'applique à tout processus Java):
Le système d'exploitation Windows limite l'allocation de mémoire d'un processus 32 bits à 2 GiB au total (par défaut).
[Vous ne pourrez] qu'allouer environ 1,5 GiB espace de pile car il y a également une autre mémoire allouée au processus (surcharge de la JVM/bibliothèque, espace permanent, etc.).
D'autres systèmes d'exploitation modernes [Linux] permettent aux processus 32 bits d'utiliser tout (ou la plupart) de l'espace adressable 4 GiB.
Ceci dit, les systèmes d’exploitation Windows 64 bits peuvent être configurés pour augmenter la limite des processus 32 bits à 4 GiB (3 GiB sur 32 bits):
http://msdn.Microsoft.com/en-us/library/windows/desktop/aa366778 (v = vs.85) .aspx
Voici comment augmenter la taille de la pagination