Vraag Maximale Java-heapgrootte van een 32-bits JVM op een 64-bits besturingssysteem


De vraag gaat niet over de maximale heapgrootte op een 32-bits besturingssysteem, aangezien 32-bits besturingssystemen een maximale adresseerbare geheugengrootte van 4 GB hebben en de maximale heapgrootte van de JVM afhankelijk is van hoeveel aangrenzend vrij geheugen kan worden gereserveerd.

Ik ben meer geïnteresseerd in het kennen van de maximale (zowel theoretisch als praktisch haalbare) heapgrootte voor een 32-bits JVM die wordt uitgevoerd in een 64-bits besturingssysteem. Kortom, ik kijk naar vergelijkbare antwoorden de cijfers in een gerelateerde vraag over SO.

Waarom een ​​32-bits JVM wordt gebruikt in plaats van een 64-bits versie, de reden is niet technisch, maar eerder administratief / bureaucratisch - het is waarschijnlijk te laat om een ​​64-bits JVM in de productieomgeving te installeren.


97
2017-09-16 18:44


oorsprong


antwoorden:


32-bits JVM's die een enkele grote hoeveelheid geheugen verwachten en onbewerkte aanwijzers gebruiken, kunnen niet meer dan 4 Gb gebruiken (aangezien dit de 32-bitslimiet is die ook geldt voor pointers). Dit omvat Sun en - ik ben er vrij zeker van - ook IBM-implementaties. Ik weet niet of bijvoorbeeld JRockit of anderen hebben een grote geheugenoptie met hun 32-bits implementaties.

Als u verwacht deze limiet te halen, moet u sterk overwegen om een ​​parallelle track te starten om een ​​64-bit JVM te valideren voor uw productieomgeving, zodat u dat gereed heeft voor wanneer de 32-bit-omgeving uitvalt. Anders moet je dat werk onder druk doen, wat nooit leuk is.


Bewerk 2014-05-15: Veelgestelde vragen over Oracle:

De maximale theoretische heap limiet voor de 32-bit JVM is 4G. Vanwege verschillende extra beperkingen zoals beschikbare swap, kernel-adresruimtegebruik, geheugenfragmentatie en VM-overhead, kan de limiet in de praktijk veel lager zijn. Op de meeste moderne 32-bits Windows-systemen varieert de maximale heapgrootte van 1,4 G tot 1,6 G. Op 32-bits Solaris-kernels is de adresruimte beperkt tot 2G. Op 64-bits besturingssystemen waarop de 32-bits VM wordt uitgevoerd, kan de maximale heapgrootte hoger zijn en 4G benaderen op veel Solaris-systemen.

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


62
2017-09-16 19:07



U kunt de Java Runtime vragen:

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

Dit rapporteert het "Max Geheugen" op basis van de standaard heap toewijzing. Dus je zou nog steeds moeten spelen -Xmx (op HotSpot). Ik vond dat draaien op Windows 7 Enterprise 64-bit, mijn 32-bits HotSpot JVM kan maximaal 1577MiB toewijzen:

[C: scratch]> java -Xmx1600M MaxMemory
Er is een fout opgetreden tijdens de initialisatie van de VM
Kon niet genoeg ruimte voor objectheap reserveren
Kon de Java-virtuele machine niet maken.
[C: scratch]> java -Xmx1590M MaxMemory
Totaal geheugen: 2031616 (1.9375 MiB)
Max. Geheugen: 1654456320 (1577.8125 MiB)
Gratis geheugen: 1840872 (1.75559234619 MiB)
[C: scratch]>

Overwegende dat met een 64-bits JVM op hetzelfde besturingssysteem, natuurlijk is het veel hoger (ongeveer 3TiB)

[C: scratch]> java -Xmx3560G MaxMemory
Er is een fout opgetreden tijdens de initialisatie van de VM
Kon niet genoeg ruimte voor objectheap reserveren
[C: scratch]> java -Xmx3550G MaxMemory
Totaal geheugen: 94240768 (89.875 MiB)
Max. Geheugen: 3388252028928 (3184151.84297 MiB)
Gratis geheugen: 93747752 (89.4048233032 MiB)
[C: scratch]>

Zoals anderen al hebben vermeld, hangt het van het besturingssysteem af.

  • Voor 32-bits Windows: het is <2 GB (Windows internals boek zegt 2 GB voor gebruikersprocessen)
  • Voor 32-bits BSD / Linux: <3 GB (uit het Devil Book)
  • Voor 32-bits MacOS X: <4 GB (uit Mac OS X-internals boek)
  • Niet zeker over 32-bit Solaris, probeer de bovenstaande code en laat het ons weten.

Voor een 64-bits host-besturingssysteem is het, als de JVM 32-bits is, nog steeds afhankelijk, waarschijnlijk zoals hierboven, zoals is aangetoond.

- UPDATE 20110905: Ik wilde alleen maar wijzen op enkele andere opmerkingen / details:

  • De hardware waarop ik dit heb uitgevoerd, was 64-bits met 6 GB aan werkelijk RAM-geheugen. Het besturingssysteem was Windows 7 Enterprise, 64-bit
  • De werkelijke hoeveelheid Runtime.MaxMemory die kan worden toegewezen, is ook afhankelijk van de besturingssystemen Werkset. Ik heb dit ooit gedaan, terwijl ik VirtualBox ook liet draaien en ik dat kon niet start met succes de HotSpot JVM met -Xmx1590M en moest kleiner worden. Dit houdt ook in dat je meer dan 1590M kunt krijgen, afhankelijk van je ingestelde werkgrootte op dat moment (hoewel ik nog steeds bewaar dat het onder 32GbB onder 2GiB komt vanwege het ontwerp van Windows)

80
2017-08-11 00:44



U specificeert niet welke OS.

Onder Windows (voor mijn toepassing - een langlopende toepassing voor risicobeheer) merkten we dat we niet verder konden gaan dan 1280 MB op Windows 32-bits. Ik betwijfel of het maken van een 32-bits JVM onder 64 bit enig verschil zou maken.

We hebben de app geport naar Linux en we hebben een 32-bits JVM op 64-bits hardware en we hebben een 2.2 GB VM vrij gemakkelijk kunnen uitvoeren.

Het grootste probleem dat je hebt is GC, afhankelijk van waar je geheugen voor gebruikt.


15
2017-09-16 19:03



Van 4.1.2 Heap Sizing:

"Voor een 32-bits procesmodel, de maximale virtuele adresgrootte van de   proces is meestal 4 GB, hoewel sommige besturingssystemen dit beperken tot   2 GB of 3 GB. De maximale heapgrootte is meestal -Xmx3800m (1600m) voor   2 GB-limieten), hoewel de daadwerkelijke beperking afhankelijk is van de toepassing.   Voor 64-bits procesmodellen is het maximum in wezen onbeperkt. "

Hier een goed antwoord gevonden: Java-maximumgeheugen op Windows XP.


13
2017-12-01 22:20



Daar hebben we recent wat ervaring mee. We zijn onlangs overgestapt van Solaris (x86-64 versie 5.10) naar Linux (RedHat x86-64) en hebben ons gerealiseerd dat we minder geheugen beschikbaar hebben voor een 32-bits JVM-proces op Linux dan Solaris.

Voor Solaris komt dit bijna op 4GB (http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit).

We hebben onze app gerund met -Xms2560m -Xmx2560m -XX: MaxPermSize = 512m -XX: PermSize = 512m zonder problemen voor Solaris voor de afgelopen paar jaar. Geprobeerd om het naar Linux te verplaatsen en we hadden problemen met willekeurige geheugenfouten bij het opstarten. We konden het alleen maar krijgen om consequent op te starten -Xms2300 -Xmx2300. Toen werden we hierover geïnformeerd door ondersteuning.

Een 32-bits proces op Linux heeft een   maximale adresseerbare adresruimte van   3 gb (3072mb) terwijl dat bij Solaris wel het geval is   de volledige 4 gb (4096mb).


12
2017-07-04 04:55



De beperkingen van een 32-bits JVM op een 64-bits besturingssysteem zijn precies hetzelfde als de beperkingen van een 32-bits JVM op een 32-bits besturingssysteem. De 32-bit JVM wordt immers uitgevoerd in een 32-bits virtuele machine (in virtualisatiestand), dus hij weet niet dat deze wordt uitgevoerd op een 64-bits besturingssysteem / computer.

Het enige voordeel van het uitvoeren van een 32-bits JVM op een 64-bits besturingssysteem versus een 32-bits besturingssysteem is dat u meer fysiek geheugen kunt hebben en daarom minder vaak hoeft te wisselen / pagen. Dit voordeel wordt echter pas echt volledig gerealiseerd wanneer u meerdere processen hebt.


9
2017-09-16 19:02



Waarom een ​​32-bits JVM wordt gebruikt in plaats van een 64-bits versie, de reden is niet technisch, maar eerder administratief / bureaucratisch ...

Toen ik voor BEA werkte, ontdekten we dat de gemiddelde toepassing eigenlijk was liep langzamer in een 64-bit JVM, dan deed hij dat in een 32-bit JVM. In sommige gevallen was de prestatieshit zo hoog als 25% langzamer. Dus, tenzij je applicatie echt al dat extra geheugen nodig heeft, kun je beter meer 32-bits servers instellen.

Zoals ik me herinner, waren de drie meest voorkomende technische rechtvaardigingen voor het gebruik van een 64-bit waarop BEA Professional Services-personeel tegenkwam:

  1. De applicatie manipuleerde meerdere massieve afbeeldingen,
  2. De applicatie deed enorm veel crunching,
  3. De applicatie had een geheugenlek, de klant was de prime op a overheidscontract, en ze wilden de tijd en de tijd niet nemen kosten van het opsporen van het geheugenlek. (Gebruik een enorm geheugen hoop zou de MTBF verhogen en de prime zou nog steeds worden betaald)

.


6
2018-03-15 19:13



De JROCKIT JVM die momenteel eigendom is van Oracle ondersteunt niet-aangrenzend heap-gebruik, waardoor de 32-bits JVM toegang heeft tot meer dan 3,8 GB geheugen wanneer de JVM wordt uitgevoerd op een 64-bits Windows-besturingssysteem. (2,8 GB bij gebruik op een 32-bits besturingssysteem).

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

De JVM kan gratis worden gedownload (registratie vereist) op

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


4
2017-12-11 10:23



Hier is wat testen onder Solaris en Linux 64-bit

Solaris 10 - SPARC - T5220-machine met 32 ​​GB RAM (en ongeveer 9 GB gratis)

$ 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: blijkbaar wijst Java niet veel daadwerkelijk geheugen met de opstarten toe. Het leek ongeveer 100 MB per gestarte instance te duren (ik startte 10)

Solaris 10 - x86 - VMWare VM met 8 GB RAM (ongeveer 3 GB gratis *)

De 3 GB vrije RAM is niet echt waar. Er is een groot stuk RAM dat ZFS-caches gebruiken, maar ik heb geen toegang tot de root om te controleren hoeveel precies

$ 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 met 4 GB RAM (ongeveer 3,8 GB gebruikt - 200 MB aan buffers en 3,1 GB aan caches, dus ongeveer 3 GB gratis)

$ 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

Dezelfde machine met 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
2018-05-03 19:03



Moet een stuk beter zijn

Voor een 32-bits JVM die wordt uitgevoerd op een 64-bits host, stel ik me voor dat wat overblijft voor de heap is, ongeacht de niet-gefragmenteerde virtuele ruimte die beschikbaar is na de JVM, zijn eigen DLL's en elk 32-bits compatibiliteitsprogramma van het besturingssysteem is geladen. Als een gok denk ik dat 3GB mogelijk zou moeten zijn, maar hoeveel beter dat is, hangt af van hoe goed je het doet in 32-bits-hostland.

Zelfs als je een gigantische 3GB-heap zou kunnen maken, zou je dat misschien ook niet willen doen, omdat GC-pauzes hierdoor mogelijk lastig worden. Sommige mensen gebruiken gewoon meer JVM's om het extra geheugen te gebruiken in plaats van één gigantisch geheugen. Ik stel me voor dat ze de JVM's nu afstemmen om beter met gigantische hopen te werken.

Het is een beetje moeilijk om precies te weten hoeveel beter je kunt doen. Ik vermoed dat je 32-bits situatie eenvoudig kan worden bepaald door te experimenteren. Het is zeker moeilijk om abstract te voorspellen, omdat er veel dingen aan bijdragen, vooral omdat de virtuele ruimte die beschikbaar is op 32-bits hosts nogal beperkt is. De heap moet in een aangrenzend virtueel geheugen bestaan, dus fragmentatie van de adresruimte voor dll's en intern gebruik van de adresruimte door de OS-kernel bepalen het bereik van mogelijke toewijzingen.

Het besturingssysteem zal een deel van de adresruimte gebruiken voor het in kaart brengen van HW-apparaten en zijn eigen dynamische toewijzingen. Hoewel dit geheugen niet is toegewezen aan de adresruimte van het Java-proces, kan de OS-kernel er niet tegelijkertijd toegang toe krijgen en uw adresruimte, waardoor de grootte van de virtuele ruimte van elk programma wordt beperkt.

Het laden van DLL's is afhankelijk van de implementatie en de release van de JVM. Het laden van de OS kernel hangt af van een groot aantal dingen, de release, de HW, hoeveel dingen het tot nu toe in kaart heeft gebracht sinds de laatste reboot, wie weet ...

samengevat

Ik wed dat je 1-2 GB krijgt in 32-bit-land, en ongeveer 3 in 64-bit, dus een algehele verbetering van ongeveer 2x.


3
2017-09-16 19:10



Op Solaris was de limiet ongeveer 3,5 GB sinds Solaris 2.5. (ongeveer 10 jaar geleden)


2
2017-12-02 06:51