Dimensione massima dell'heap Java di una JVM a 32 bit su un sistema operativo a 64 bit


La domanda non riguarda la dimensione massima dell'heap su un sistema operativo a 32 bit, dato che i sistemi operativi a 32 bit hanno una dimensione massima di memoria indirizzabile di 4 GB e che la dimensione massima dell'heap della JVM dipende da quanta memoria libera contigua può essere riservata.

Sono più interessato a conoscere la dimensione massima (sia teorica che praticamente realizzabile) dell'heap per una JVM a 32 bit in esecuzione in un sistema operativo a 64 bit. Fondamentalmente, sto guardando risposte simili a le figure in una domanda correlata su SO.

Come per il motivo per cui viene utilizzata una JVM a 32 bit invece di una a 64 bit, il motivo non è tecnico ma piuttosto amministrativo/burocratico-probabilmente è troppo tardi per installare una JVM a 64 bit nell'ambiente di produzione.

Author: Community, 2009-09-16

16 answers

Le JVM a 32 bit che si aspettano di avere un singolo grande blocco di memoria e utilizzano puntatori grezzi non possono utilizzare più di 4 Gb (poiché questo è il limite di 32 bit che si applica anche ai puntatori). Questo include Sun e - sono abbastanza sicuro-anche implementazioni IBM. Non so se ad esempio JRockit o altri hanno una grande opzione di memoria con le loro implementazioni a 32 bit.

Se si prevede di raggiungere questo limite, è consigliabile avviare una traccia parallela convalidando una JVM a 64 bit per il proprio ambiente di produzione in modo da avere che pronto per quando l'ambiente a 32 bit si rompe. Altrimenti si dovrà fare quel lavoro sotto pressione, che non è mai bello.


Modifica 2014-05-15: Oracle FAQ:

Il limite massimo teorico di heap per la JVM a 32 bit è 4G. A causa di vari vincoli aggiuntivi come lo swap disponibile, l'utilizzo dello spazio degli indirizzi del kernel, la frammentazione della memoria e l'overhead della VM, in pratica il limite può essere molto più basso. Sulla maggior parte delle moderne finestre a 32 bit sistemi la dimensione massima dell'heap varia da 1,4 G a 1,6 G. Nei kernel Solaris a 32 bit lo spazio degli indirizzi è limitato a 2G. Nei sistemi operativi a 64 bit che eseguono la VM a 32 bit, la dimensione massima dell'heap può essere superiore, avvicinandosi a 4G su molti sistemi Solaris.

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

 62
Author: Thorbjørn Ravn Andersen, 2017-08-04 10:36:43

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

Questo riporterà la "Memoria massima" in base all'allocazione heap predefinita. Quindi dovresti ancora giocare con -Xmx (su HotSpot). Ho scoperto che in esecuzione su Windows 7 Enterprise a 64 bit, la mia JVM HotSpot a 32 bit può allocare fino a 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]>

Mentre con una JVM a 64 bit sullo stesso sistema operativo, ovviamente è molto più alta (circa 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]>

Come altri hanno già detto, dipende dal OPERATIVO.

  • Per Windows a 32 bit: sarà Windows internals book dice 2GB per i processi utente)
  • Per BSD / Linux a 32 bit:
  • Per macOS X a 32 bit: Interni di Mac OS X libro)
  • Non sei sicuro di Solaris a 32 bit, prova il codice sopra e faccelo sapere.

Per un sistema operativo host a 64 bit, se la JVM è a 32 bit, dipenderà comunque, molto probabilmente come sopra come dimostrare.

-- AGGIORNAMENTO 20110905: Volevo solo sottolineare alcune altre osservazioni / dettagli:

  • L'hardware su cui ho eseguito questo era a 64 bit con 6 GB di RAM effettiva installata. Il sistema operativo era Windows 7 Enterprise, a 64 bit
  • La quantità effettiva di Runtime.MaxMemoryche può essere allocata dipende anche dal working set del sistema operativo. Una volta l'ho eseguito mentre avevo anche VirtualBox in esecuzione e ho scoperto che potevonon con successo avviare la JVM HotSpot con -Xmx1590M e ha dovuto andare più piccolo. Ciò implica anche che potresti ottenere più di 1590M a seconda delle dimensioni del tuo set di lavoro al momento (anche se continuo a mantenere che sarà sotto 2GiB per 32 bit a causa del design di Windows)
 80
Author: mike, 2015-04-13 11:38:03

Non si specifica quale sistema operativo.

Sotto Windows (per la mia applicazione - un'applicazione di gestione del rischio di lunga durata) abbiamo osservato che non potevamo andare oltre i 1280 MB su Windows 32bit. Dubito che l'esecuzione di una JVM a 32 bit sotto 64 bit farebbe alcuna differenza.

Abbiamo portato l'app su Linux e stiamo eseguendo una JVM a 32 bit su hardware a 64 bit e abbiamo avuto una VM da 2,2 GB in esecuzione abbastanza facilmente.

Il problema più grande che potresti avere è GC a seconda di cosa stai usando memoria per.

 16
Author: Fortyrunner, 2009-09-16 19:03:12

Da 4.1.2 Dimensionamento dell'heap:

"Per un modello di processo a 32 bit, la dimensione massima dell'indirizzo virtuale il processo è in genere 4 GB, anche se alcuni sistemi operativi limitano questo a 2 GB o 3 GB. La dimensione massima dell'heap è in genere-Xmx3800m (1600m) per 2 Limiti GB), anche se la limitazione effettiva dipende dall'applicazione. Per i modelli di processo a 64 bit, il massimo è essenzialmente illimitato."

Trovato una risposta abbastanza buona qui: Memoria massima Java su Windows XP .

 13
Author: djangofan, 2017-05-23 12:26:27

Recentemente abbiamo avuto una certa esperienza con questo. Abbiamo portato da Solaris (x86-64 Versione 5.10) a Linux (RedHat x86-64) di recente e ci siamo resi conto che abbiamo meno memoria disponibile per un processo JVM a 32 bit su Linux rispetto a Solaris.

Per Solaris questo arriva quasi a 4GB (http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit).

Abbiamo eseguito la nostra app con - Xms2560m - Xmx2560m-XX: MaxPermSize=512m-XX: PermSize=512m senza problemi su Solaris negli ultimi due anni. Ho provato a spostarlo su Linux e abbiamo avuto problemi con errori casuali di memoria all'avvio. Potremmo solo farlo avviare in modo coerente su -Xms2300-Xmx2300. Poi siamo stati informati di questo dal supporto.

Un processo a 32 bit su Linux ha un spazio massimo indirizzabile di 3gb (3072mb) mentre su Solaris è il pieno 4 gb (4096 mb).

 12
Author: chinto, 2012-10-29 04:31:48

Le limitazioni di una JVM a 32 bit su un sistema operativo a 64 bit saranno esattamente le stesse delle limitazioni di una JVM a 32 bit su un sistema operativo a 32 bit. Dopo tutto, la JVM a 32 bit verrà eseguita in una macchina virtuale a 32 bit (nel senso della virtualizzazione), quindi non saprà che è in esecuzione su un sistema operativo/macchina a 64 bit.

L'unico vantaggio di eseguire una JVM a 32 bit su un sistema operativo a 64 bit rispetto a un sistema operativo a 32 bit è che si può avere più memoria fisica, e quindi si verificherà lo scambio/paging meno frequentemente. Questo vantaggio è solo veramente pienamente realizzato quando si dispone di più processi, tuttavia.

 9
Author: Laurence Gonsalves, 2009-09-16 19:02:05

Per quanto riguarda il motivo per cui viene utilizzata una JVM a 32 bit al posto di una a 64 bit, il motivo non è tecnico ma piuttosto amministrativo/burocratico ...

Quando lavoravo per BEA, abbiamo scoperto che l'applicazione media in realtà corse più lentamente in una JVM a 64 bit, quindi lo ha fatto quando è in esecuzione in una JVM a 32 bit. In alcuni casi, il successo delle prestazioni è stato più lento del 25%. Quindi, a meno che la tua applicazione non abbia davvero bisogno di tutta quella memoria extra, è meglio impostare più 32 bit server.

Come ricordo, le tre giustificazioni tecniche più comuni per l'utilizzo di un 64-bit che il personale di BEA professional services ha incontrato erano:

  1. L'applicazione stava manipolando più immagini massicce,
  2. L'applicazione stava facendo massiccia scricchiolio numero,
  3. L'applicazione ha avuto una perdita di memoria, il cliente era il primo su un contratto di governo, e non volevano prendere il tempo e il spese per rintracciare la perdita di memoria. (Usando un memoria massiccia heap aumenterebbe il MTBF e il primo sarebbe ancora pagato)

.

 6
Author: user1564349, 2013-03-15 19:13:08

La JVM JROCKIT attualmente di proprietà di Oracle supporta l'utilizzo di heap non contigui, consentendo così alla JVM a 32 bit di accedere a più di 3,8 GB di memoria quando la JVM è in esecuzione su un sistema operativo Windows a 64 bit. (2,8 GB quando si esegue su un sistema operativo a 32 bit).

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

La JVM può essere scaricata liberamente (è richiesta la registrazione) a

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

 4
Author: Dale, 2011-12-11 10:23:55

Ecco alcuni test sotto Solaris e Linux a 64 bit

Solaris 10 - SPARC-T5220 macchina con 32 GB di RAM (e circa 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: Apparentemente Java non alloca molta memoria effettiva con l'avvio. Sembrava prendere solo circa 100 MB per istanza avviata (ho iniziato 10)

Solaris 10 - x86-VMware VM con 8 GB di RAM (circa 3 GB gratis*)

I 3 GB di RAM libera non è proprio vero. C'è una grande quantità di RAM che le cache ZFS usano, ma non ho accesso root per verificare quanto esattamente

$ 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 con 4 GB di RAM (circa 3,8 GB utilizzati - 200 MB in buffer e 3,1 GB in cache, quindi circa 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

Stessa macchina che utilizza 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
Author: ih.ng, 2013-05-03 20:43:51

Dovrebbe essere molto meglio

Per una JVM a 32 bit in esecuzione su un host a 64 bit, immagino che ciò che rimane per l'heap sarà qualsiasi spazio virtuale non frammentato disponibile dopo la JVM, le sue DLL e qualsiasi materiale di compatibilità a 32 bit del sistema operativo sia stato caricato. Come ipotesi selvaggia, penserei che 3GB dovrebbe essere possibile, ma quanto meglio dipende da quanto bene stai facendo in 32-bit-host-land.

Inoltre, anche se potresti creare un heap gigante da 3 GB, potresti non volerlo, poiché questo causa pause GC a diventare potenzialmente fastidioso. Alcune persone eseguono solo più JVM per usare la memoria extra piuttosto che una gigante. Immagino che stiano sintonizzando le JVM in questo momento per funzionare meglio con cumuli giganti.

È un po ' difficile sapere esattamente quanto meglio si può fare. Immagino che la tua situazione a 32 bit possa essere facilmente determinata dall'esperimento. È certamente difficile prevedere astrattamente, poiché molte cose vi entrano, in particolare perché lo spazio virtuale disponibile su 32 bit hosts è piuttosto vincolato.. L'heap deve esistere nella memoria virtuale contigua, quindi la frammentazione dello spazio degli indirizzi per le dll e l'uso interno dello spazio degli indirizzi da parte del kernel del sistema operativo determineranno l'intervallo di allocazioni possibili.

Il sistema operativo utilizzerà parte dello spazio degli indirizzi per mappare i dispositivi HW e le proprie allocazioni dinamiche. Mentre questa memoria non è mappata nello spazio degli indirizzi del processo Java, il kernel del sistema operativo non può accedervi e lo spazio degli indirizzi contemporaneamente, quindi limiterà la dimensione dello spazio virtuale di qualsiasi programma.

Il caricamento delle DLL dipende dall'implementazione e dal rilascio della JVM. Il caricamento del kernel del sistema operativo dipende da un numero enorme di cose, il rilascio, l'HW, quante cose ha mappato finora dall'ultimo riavvio, chi lo sa...

In sintesi

Scommetto che ottieni 1-2 GB in 32-bit-land e circa 3 in 64-bit, quindi un miglioramento complessivo di circa 2x.

 3
Author: DigitalRoss, 2009-09-16 19:48:04

Su Solaris il limite è stato di circa 3,5 GB da Solaris 2,5. (circa 10 anni fa)

 2
Author: Peter Lawrey, 2009-12-02 06:51:24

Stavo avendo gli stessi problemi con la JVM che App Inventor per Android Blocks Editor utilizza. Imposta l'heap a 925m max. Questo non è sufficiente, ma non ho potuto impostarlo più di circa 1200m, a seconda di vari fattori casuali sulla mia macchina.

Ho scaricato Nightly, il browser beta a 64 bit da Firefox e anche la versione JAVA 7 a 64 bit.

Non ho ancora trovato il mio nuovo limite di heap, ma ho appena aperto una JVM con una dimensione heap di 5900m. Nessun problema!

Sto correndo Vittoria 7 64 bit finale su una macchina con 24gb di RAM.

 1
Author: user1652651, 2012-10-02 09:43:50

Ho provato a impostare la dimensione dell'heap fino a 2200M su una macchina Linux a 32 bit e JVM ha funzionato bene. La JVM non è iniziata quando l'ho impostata su 2300M.

 0
Author: Priya, 2009-10-10 01:12:45

Un altro punto qui per hotspot JVM a 32 bit:- la capacità heap nativa = 4 Gig-Java Heap-PermGen;

Può diventare particolarmente complicato per la JVM a 32 bit poiché l'Heap Java e l'Heap nativo sono in gara. Il più grande è il tuo Heap Java, più piccolo è l'Heap nativo. Tentativo di configurare un Heap di grandi dimensioni per una VM a 32 bit ad esempio2,5 GB+ aumenta il rischio di OutOfMemoryError nativo a seconda dell'impronta dell'applicazione, numero di fili ecc.

 0
Author: ajay29, 2015-02-05 18:50:06

Teorico 4gb, ma in pratica (per 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
Author: pk.shulgin, 2016-11-24 17:55:29