Maximale Java-Heap-Größe einer 32-Bit-JVM unter einem 64-Bit-Betriebssystem

107

Die Frage bezieht sich nicht auf die maximale Heap-Größe eines 32-Bit-Betriebssystems, da 32-Bit-Betriebssysteme eine maximal adressierbare Speichergröße von 4 GB haben und die maximale Heap-Größe der JVM davon abhängt, wie viel zusammenhängender freier Speicher reserviert werden kann.

Ich bin mehr daran interessiert, die maximale (sowohl theoretische als auch praktisch erreichbare) Heap-Größe für eine 32-Bit-JVM zu kennen, die in einem 64-Bit-Betriebssystem ausgeführt wird. Grundsätzlich betrachte ich Antworten ähnlich den Zahlen in einer verwandten Frage zu SO .

Der Grund, warum eine 32-Bit-JVM anstelle einer 64-Bit-JVM verwendet wird, ist nicht technischer, sondern eher administrativer / bürokratischer Natur. Es ist wahrscheinlich zu spät, eine 64-Bit-JVM in der Produktionsumgebung zu installieren.

Vineet Reynolds
quelle

Antworten:

70

32-Bit-JVMs, die einen einzigen großen Speicherblock erwarten und Rohzeiger verwenden, können nicht mehr als 4 GB verwenden (da dies die 32-Bit-Grenze ist, die auch für Zeiger gilt). Dies schließt Sun und - da bin ich mir ziemlich sicher - auch IBM Implementierungen ein. Ich weiß nicht, ob zB JRockit oder andere mit ihren 32-Bit-Implementierungen eine große Speicheroption haben.

Wenn Sie damit rechnen, dieses Limit zu erreichen, sollten Sie unbedingt eine parallele Spur starten, die eine 64-Bit-JVM für Ihre Produktionsumgebung validiert, damit Sie diese bereit haben, wenn die 32-Bit-Umgebung ausfällt. Andernfalls müssen Sie diese Arbeit unter Druck ausführen, was niemals schön ist.


Bearbeiten 15.05.2014: Oracle-FAQ:

Die maximale theoretische Heap-Grenze für die 32-Bit-JVM beträgt 4G. Aufgrund verschiedener zusätzlicher Einschränkungen wie verfügbarem Swap, Verwendung des Kernel-Adressraums, Speicherfragmentierung und VM-Overhead kann das Limit in der Praxis viel niedriger sein. Auf den meisten modernen 32-Bit-Windows-Systemen liegt die maximale Heap-Größe zwischen 1,4 G und 1,6 G. Auf 32-Bit-Solaris-Kerneln ist der Adressraum auf 2G beschränkt. Unter 64-Bit-Betriebssystemen, auf denen die 32-Bit-VM ausgeführt wird, kann die maximale Heap-Größe höher sein und sich auf vielen Solaris-Systemen 4G nähern.

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

Thorbjørn Ravn Andersen
quelle
Kein Arbeitsdruck hier. Ich weiß, dass überhaupt eine 64-Bit-JVM installiert werden sollte. Aber ich habe darüber nachgedacht, wie eine 32-Bit-JVM in einer Umgebung mit mehr Ressourcen funktionieren würde.
Vineet Reynolds
1
Ist es nicht etwa 2 GB wegen der Unterschriften? Oder ist das nur die Sun JVM?
Sebastian Ganslandt
9
Zeiger sind nicht signiert - es ist nicht sinnvoll, von negativen Speicherstellen zu sprechen.
Thorbjørn Ravn Andersen
12
Nein, es sind keine 2 GB wegen der Signiertheit. Ein Teil des 4-GB-Adressraums ist jedoch für den Betriebssystemkern reserviert. Bei normalen Consumer-Versionen von Windows beträgt das Limit 2 GB. Unter Linux- und Serverversionen von Windows (32-Bit) beträgt das Limit 3 GB pro Prozess.
Jesper
3
@Jesper Ich habe mich gefragt, ob für eine 32-Bit-JVM, die auf einem 64-Bit-Betriebssystem ausgeführt wird, möglicherweise ein vollständiger Adressraum von 4 GB verfügbar ist.
Thorbjørn Ravn Andersen
90

Sie können die Java Runtime fragen:

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

Dies meldet den "Maximaler Speicher" basierend auf der Standard-Heap-Zuordnung. Sie müssten also immer noch mit -Xmx(auf HotSpot ) spielen. Ich fand, dass unter Windows 7 Enterprise 64-Bit läuft, meine 32-Bit- HotSpot-JVM unter bis zu 1577 MB zuweisen kann:

[C: Scratch]> Java -Xmx1600M MaxMemory
Bei der Initialisierung der VM ist ein Fehler aufgetreten
Es konnte nicht genügend Speicherplatz für den Objekthaufen reserviert werden
Die virtuelle Java-Maschine konnte nicht erstellt werden.
[C: Scratch]> Java -Xmx1590M MaxMemory
Gesamtspeicher: 2031616 (1,9375 MiB)
Maximaler Speicher: 1654456320 (1577,8125 MiB)
Freier Speicher: 1840872 (1.75559234619 MiB)
[C: Kratzer]>

Während mit einer 64-Bit- JVM auf demselben Betriebssystem, ist es natürlich viel höher (ungefähr 3 TB)

[C: Scratch]> Java -Xmx3560G MaxMemory
Bei der Initialisierung der VM ist ein Fehler aufgetreten
Es konnte nicht genügend Speicherplatz für den Objekthaufen reserviert werden
[C: Scratch]> Java -Xmx3550G MaxMemory
Gesamtspeicher: 94240768 (89,875 MiB)
Maximaler Speicher: 3388252028928 (3184151.84297 MiB)
Freier Speicher: 93747752 (89.4048233032 MiB)
[C: Kratzer]>

Wie andere bereits erwähnt haben, hängt es vom Betriebssystem ab.

  • Für 32-Bit-Windows: <2 GB (im Windows-Interna-Buch sind 2 GB für Benutzerprozesse angegeben).
  • Für 32-Bit-BSD / Linux: <3 GB (aus dem Devil Book)
  • Für 32-Bit-MacOS X: <4 GB (aus dem internen Mac OS X- Buch)
  • Sie sind sich bei 32-Bit-Solaris nicht sicher. Probieren Sie den obigen Code aus und lassen Sie es uns wissen.

Wenn bei einem 64-Bit-Host-Betriebssystem die JVM 32-Bit ist, hängt dies immer noch davon ab, höchstwahrscheinlich wie oben gezeigt.

- UPDATE 20110905 : Ich wollte nur auf einige andere Beobachtungen / Details hinweisen:

  • Die Hardware, auf der ich dies ausführte, war 64-Bit mit 6 GB tatsächlich installiertem RAM. Das Betriebssystem war Windows 7 Enterprise, 64-Bit
  • Die tatsächliche Menge Runtime.MaxMemory, die zugewiesen werden kann, hängt auch vom Arbeitssatz des Betriebssystems ab . Ich habe dies einmal ausgeführt, während VirtualBox ausgeführt wurde, und festgestellt, dass ich die HotSpot-JVM nicht erfolgreich starten konnte -Xmx1590Mund kleiner werden musste. Dies bedeutet auch, dass Sie abhängig von der Größe Ihres Arbeitssatzes zu diesem Zeitpunkt möglicherweise mehr als 1590 MB erhalten (obwohl ich aufgrund des Windows-Designs immer noch davon ausgehe, dass der Wert für 32-Bit unter 2 GB liegt).
Mike
quelle
13
Ich mag es, dass Sie tatsächlich getestet haben, anstatt Vermutungen anzustellen.
Jim Hurne
3
@ Djangofan ist richtig. Das Programm sollte durch 1.048.576 (1024 * 1024 oder 2 ^ 20) und nicht durch 104.856 geteilt werden. Aber das ist nur eine Ausstellungssache. Wie Sie dem Befehl entnehmen können, hat er nur versucht, die maximale Heap-Größe auf 1.590 MiB festzulegen.
Jim Hurne
1
Sehr coole Antwort (ich möchte die Antwort sagen ) mit einem Codebeispiel und Details zu allen Betriebssystemen.
TGP1994
3
Nach meinem vorherigen Kommentar: Die jdocs ( mindestens für Windows) geben an, dass den Parametern -Xmx und -Xms ein Wert zugewiesen werden muss, der ein Vielfaches von 1024 ist ... Ich bin mir nicht sicher, ob 1590 ist, daher finde ich das seltsam Ergebnisse sind zu erwarten.
TGP1994
4
Gut gefleckter TGP1994. Ich denke, da ich 'M' und 'G' Vielfache angegeben habe, wird die Größe (in Bytes) ohnehin ein Vielfaches von 1024 Bytes sein. zB 1590M wird auf 1590 * (1024 * 1024) = 1667235840 Bytes (1628160KiB - natürlich ein gerades Vielfaches von 1024) analysiert.
Mike
16

Sie geben nicht an, welches Betriebssystem.

Unter Windows (für meine Anwendung - eine lang laufende Risikomanagement-Anwendung) haben wir festgestellt, dass wir unter Windows 32bit nicht weiter als 1280 MB gehen können. Ich bezweifle, dass das Ausführen einer 32-Bit-JVM unter 64-Bit einen Unterschied machen würde.

Wir haben die App auf Linux portiert und führen eine 32-Bit-JVM auf 64-Bit-Hardware aus. Eine 2,2-GB-VM konnte problemlos ausgeführt werden.

Das größte Problem, das Sie möglicherweise haben, ist GC, je nachdem, wofür Sie Speicher verwenden.

Fortyrunner
quelle
Ich würde es vorziehen, die Einschränkung für Solaris 10 zu kennen, aber das ist nur für mein Problem. Würde gerne auch für andere Betriebssysteme wissen, für einen regnerischen Tag :)
Vineet Reynolds
Ich bin mir bei Solaris nicht sicher. Ich würde erwarten, dass die VM-Größe ziemlich groß ist. Meine Erfahrung mit Java unter Solaris war vor einigen Jahren. Und als Sun VM auf einem Sun OS auf Sun-Hardware haben die Dinge ziemlich gut funktioniert. Ich wurde auch zu der Überzeugung gebracht, dass es unter Solaris weniger GC-Probleme als unter Linux / Windows gab.
Fortyrunner
Welches Windows war das? Ich glaube, dass die Serverversionen von Windows 32-Bit große Speichermengen viel besser verarbeiten können.
Thorbjørn Ravn Andersen
Ah, endlich eine Erwähnung des Betriebssystems ;-) Sie haben einen 64-Bit-Kernel installiert?
Thorbjørn Ravn Andersen
Es war Win2k Server. Ein Wechsel zu Win2k3 (die Dinge bewegen sich langsam ..) war zu spät und wir wechselten stattdessen zu Linux.
Fortyrunner
14

Ab 4.1.2 Heap-Größe :

"Bei einem 32-Bit-Prozessmodell beträgt die maximale Größe der virtuellen Adresse des Prozesses normalerweise 4 GB, obwohl einige Betriebssysteme dies auf 2 GB oder 3 GB beschränken. Die maximale Größe des Heapspeichers beträgt normalerweise -Xmx3800m (1600m) für 2 GB ), obwohl die tatsächliche Einschränkung anwendungsabhängig ist. Bei 64-Bit-Prozessmodellen ist das Maximum im Wesentlichen unbegrenzt. "

Ich habe hier eine ziemlich gute Antwort gefunden: Maximaler Java-Speicher unter Windows XP .

Djangofan
quelle
12

Wir haben kürzlich einige Erfahrungen damit gemacht. Wir haben kürzlich von Solaris (x86-64 Version 5.10) auf Linux (RedHat x86-64) portiert und festgestellt, dass für einen 32-Bit-JVM-Prozess unter Linux weniger Speicher verfügbar ist als für Solaris.

Für Solaris sind es fast 4 GB (http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit).

Wir haben unsere App mit -Xms2560m -Xmx2560m -XX: MaxPermSize = 512m -XX: PermSize = 512m ohne Probleme unter Solaris in den letzten Jahren ausgeführt. Wir haben versucht, es auf Linux zu verschieben, und beim Start gab es Probleme mit zufälligen Speicherfehlern. Wir konnten es nur dazu bringen, konsistent auf -Xms2300 -Xmx2300 zu starten . Dann wurden wir durch Unterstützung darauf hingewiesen.

Ein 32-Bit-Prozess unter Linux hat einen maximal adressierbaren Adressraum von 3 GB (3072 MB), während er unter Solaris die vollen 4 GB (4096 MB) beträgt.

Chinto
quelle
Der Grund für die Antwort des Supports liegt darin, wie viel adressierbarer Speicher für einen Prozess verfügbar ist. Dies hängt vom Linux-Kernel und sogar von der Hardware ab. Theoretisch ist der adressierbare Speicher auf 2 ^ 32 = 4G begrenzt (und die Java-Heap-Größe wäre geringer als diese). Dies kann jedoch (theoretisch) mit Hugemem und PAE erweitert werden. Ich habe das nicht versucht.
Vineet Reynolds
9

Die Einschränkungen einer 32-Bit-JVM unter einem 64-Bit-Betriebssystem entsprechen genau den Einschränkungen einer 32-Bit-JVM unter einem 32-Bit-Betriebssystem. Immerhin wird die 32-Bit-JVM in einer virtuellen 32-Bit-Maschine (im Sinne der Virtualisierung) ausgeführt, sodass sie nicht weiß, dass sie auf einem 64-Bit-Betriebssystem / einer 64-Bit-Maschine ausgeführt wird.

Der einzige Vorteil beim Ausführen einer 32-Bit-JVM auf einem 64-Bit-Betriebssystem gegenüber einem 32-Bit-Betriebssystem besteht darin, dass Sie über mehr physischen Speicher verfügen können und daher seltener auf Swapping / Paging stoßen. Dieser Vorteil wird jedoch nur dann wirklich voll ausgeschöpft, wenn Sie mehrere Prozesse haben.

Laurence Gonsalves
quelle
1
Je nach Hardware und Virtualisierung kann es geringfügige Unterschiede geben. Ein Teil des adressierbaren 4-GB-Speicherplatzes wird im Allgemeinen für Geräte mit Speicherzuordnung verwendet. Die Virtualisierungsschicht kann denselben Speicherbedarf haben wie die physischen Geräte auf dem Computer.
Eric J.
8
Nicht ganz. In einem 64-Bit-Computer ist mehr Platz für die JVM vorhanden, da der 32-Bit-Adressraum nicht mit dem Betriebssystem oder den Hardwareschnittstellen geteilt werden muss.
Thorbjørn Ravn Andersen
Das stimmt, aber das bedeutet nur, dass Ihre 32-Bit-virtuelle Maschine möglicherweise einen geringfügig anderen Overhead hat als eine 32-Bit-tatsächliche Maschine (entweder schlechter oder besser). In beiden Fällen führen Sie die JVM auf einem 32-Bit-Computer (real oder virtuell) aus und unterliegen daher den Standard-32-Bit-Einschränkungen. dh: eine absolute Obergrenze von 4 GB.
Laurence Gonsalves
Thorbjørn: Das Betriebssystem und die Hardwareschnittstellen müssen noch der 32-Bit-VM zugeordnet werden. Die genaue Menge des Abhörens mag unterschiedlich sein, aber es wird immer noch da sein. Wenn Sie es unter einem 64-Bit-Betriebssystem virtualisieren können, was hindert Sie daran, es unter einem 32-Bit-Betriebssystem zu virtualisieren? Dies ist der virtuelle Speicher, über den wir sprechen.
Laurence Gonsalves
2
LG: Ich bin mit Ihrer ursprünglichen Antwort nicht einverstanden. Der Betriebssystemkernel und jeder von ihm zugeordnete HW- und Busadressraum verbrauchen einen Großteil des Adressraums, und obwohl dieser nicht dem Benutzerprogramm zugeordnet ist, verringert er den "verbleibenden" Betrag, nachdem sich das Betriebssystem eingerichtet hat. Dies ist eine beträchtliche Menge eines 4 GB 32-Bit-Speicherplatzes. Traditionell bedeutet dies, dass ungefähr 25% bis 75% der 4 GB für Benutzerprozesse nicht verfügbar sind. :-) Kernel Hacker
DigitalRoss
6

Der Grund, warum eine 32-Bit-JVM anstelle einer 64-Bit-JVM verwendet wird, ist nicht technisch, sondern eher administrativ / bürokratisch ...

Als ich für BEA arbeitete, stellten wir fest, dass die durchschnittliche Anwendung in einer 64-Bit-JVM tatsächlich langsamer lief als in einer 32-Bit-JVM. In einigen Fällen war der Leistungseinbruch bis zu 25% langsamer. Wenn Ihre Anwendung nicht wirklich den gesamten zusätzlichen Speicher benötigt, sollten Sie mehr 32-Bit-Server einrichten.

Soweit ich mich erinnere, waren die drei häufigsten technischen Gründe für die Verwendung eines 64-Bit-Systems, auf das BEA Professional Services-Mitarbeiter gestoßen sind:

  1. Die Anwendung manipulierte mehrere massive Bilder,
  2. Die Anwendung machte massive Zahlenkalkulation,
  3. Die Anwendung hatte einen Speicherverlust, der Kunde war der Hauptverantwortliche für einen Regierungsvertrag, und er wollte sich nicht die Zeit und die Kosten nehmen, um den Speicherverlust aufzuspüren. (Die Verwendung eines massiven Speicherhaufens würde die MTBF erhöhen und der Prime würde immer noch bezahlt werden)

.

user1564349
quelle
Das ist schön, dass Sie aus erster Hand Ratschläge geben,
BEAs
4

Die JROCKIT-JVM, die derzeit im Besitz von Oracle ist, unterstützt die nicht zusammenhängende Heap-Nutzung, sodass die 32-Bit-JVM auf mehr als 3,8 GB Speicher zugreifen kann, wenn die JVM unter einem 64-Bit-Windows-Betriebssystem ausgeführt wird. (2,8 GB bei Ausführung unter einem 32-Bit-Betriebssystem).

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

Die JVM kann unter kostenlos heruntergeladen werden (Registrierung erforderlich)

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

Tal
quelle
4

Hier finden Sie einige Tests unter Solaris und Linux 64-Bit

Solaris 10 - SPARC - T5220 Maschine mit 32 GB RAM (und ca. 9 GB frei)

$ 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

Übrigens: Anscheinend weist Java beim Start nicht viel tatsächlichen Speicher zu. Es schien nur ungefähr 100 MB pro gestarteter Instanz zu dauern (ich habe 10 gestartet)

Solaris 10 - x86 - VMWare VM mit 8 GB RAM (ca. 3 GB frei *)

Der 3 GB freie RAM ist nicht wirklich wahr. Es gibt einen großen Teil des Arbeitsspeichers, den ZFS-Caches verwenden, aber ich habe keinen Root-Zugriff, um zu überprüfen, wie viel genau

$ 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 mit 4 GB RAM (ca. 3,8 GB verwendet - 200 MB in Puffern und 3,1 GB in Caches, also ca. 3 GB frei)

$ 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

Gleiche Maschine mit 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.
quelle
Hier finden Sie einige nützliche Testergebnisse für die Plattformen, die wir vermisst haben. Gute Arbeit auch mit der Verwendung von Datei- und Speicherabbildern.
Mike
3

Sollte viel besser sein

Für eine 32-Bit-JVM, die auf einem 64-Bit-Host ausgeführt wird, kann ich mir vorstellen, dass für den Heap der unfragmentierte virtuelle Speicherplatz übrig bleibt, der verfügbar ist, nachdem die JVM, ihre eigenen DLLs und alle 32-Bit-Kompatibilitätsmaterialien für das Betriebssystem geladen wurden. Als wilde Vermutung würde ich denken, dass 3 GB möglich sein sollten, aber wie viel besser das ist, hängt davon ab, wie gut Sie im 32-Bit-Host-Land abschneiden.

Selbst wenn Sie einen riesigen 3-GB-Heap erstellen könnten, möchten Sie dies möglicherweise nicht, da dies dazu führen kann, dass GC-Pausen möglicherweise problematisch werden. Einige Leute betreiben einfach mehr JVMs, um den zusätzlichen Speicher zu nutzen, als einen riesigen. Ich kann mir vorstellen, dass sie gerade die JVMs optimieren, um besser mit riesigen Haufen zu arbeiten.

Es ist ein wenig schwierig, genau zu wissen, wie viel besser Sie tun können. Ich denke, Ihre 32-Bit-Situation kann leicht durch Experimente bestimmt werden. Es ist sicherlich schwer abstrakt vorherzusagen, da viele Dinge eine Rolle spielen, insbesondere weil der auf 32-Bit-Hosts verfügbare virtuelle Speicherplatz eher eingeschränkt ist. Der Heap muss im zusammenhängenden virtuellen Speicher vorhanden sein, also Fragmentierung des Adressraums für DLLs und die interne Verwendung des Adressraums durch den Betriebssystemkern bestimmen den Bereich möglicher Zuordnungen.

Das Betriebssystem verwendet einen Teil des Adressraums für die Zuordnung von HW-Geräten und seine eigenen dynamischen Zuordnungen. Obwohl dieser Speicher nicht dem Adressraum des Java-Prozesses zugeordnet ist, kann der Betriebssystemkernel nicht gleichzeitig auf ihn und Ihren Adressraum zugreifen, sodass die Größe des virtuellen Raums eines Programms begrenzt wird.

Das Laden von DLLs hängt von der Implementierung und der Freigabe der JVM ab. Das Laden des Betriebssystemkerns hängt von einer Vielzahl von Faktoren ab, der Veröffentlichung, der Hardware und der Anzahl der Dinge, die seit dem letzten Neustart bisher zugeordnet wurden. Wer weiß ...

Zusammenfassend

Ich wette, Sie erhalten 1-2 GB in 32-Bit-Land und ungefähr 3 in 64-Bit, also eine allgemeine Verbesserung von ungefähr 2x .

DigitalRoss
quelle
1
Leider steht mir keine 64-Bit-Umgebung zur Verfügung, in der ich mit dem Xmx-Flag experimentieren könnte. Der mir bekannte hat eine riesige (32 * n) GB RAM-Menge zur Verfügung, aber außerhalb der Grenzen. Aus diesem Grund wollte ich wissen, wie eine 32-Bit-JVM ohne alle Einschränkungen funktioniert, denen sie normalerweise in einer 32-Bit-Welt ausgesetzt ist.
Vineet Reynolds
Nun, gute Frage. Ich bin sicher, die grundlegende Antwort lautet "es wird besser funktionieren".
DigitalRoss
Ok, ich habe meine Antwort bearbeitet, um mich ein bisschen mehr auf Ihre eigentliche Frage zu konzentrieren. :-)
DigitalRoss
1
≅ 3 GB in 64-Bit klingen genau richtig. Thorbjørn hatte bereits angegeben, warum es theoretisch 4 GB nicht überschreiten kann. Schade, dass ich zwei Antworten nicht akzeptieren kann.
Vineet Reynolds
Wenn Sie eine große Box haben, können Sie mit einem 64-Bit-Solaris in einer virtuellen Box experimentieren (die die beste Solaris-Gastunterstützung bietet).
Thorbjørn Ravn Andersen
2

Unter Solaris lag das Limit seit Solaris 2.5 bei etwa 3,5 GB. (vor ungefähr 10 Jahren)

Peter Lawrey
quelle
Ich werde damit experimentieren und Oracle Solaris Express 11 verwenden.
Djangofan
1
@ Peter Lawrey Uhm .. Solaris 2.5 war vor fast 20 Jahren, wenn man das Erscheinungsdatum von Mai 1996 berücksichtigt ... natürlich hat es erst um 2005 EOL.
cb88
1

Ich hatte dieselben Probleme mit der JVM, die App Inventor für Android Blocks Editor verwendet. Es setzt den Haufen auf 925m max. Dies ist nicht genug, aber ich konnte es nicht mehr als ungefähr 1200 m einstellen, abhängig von verschiedenen zufälligen Faktoren auf meiner Maschine.

Ich habe Nightly, den 64-Bit-Beta-Browser von Firefox, sowie die 64-Bit-Version von JAVA 7 heruntergeladen.

Ich habe mein neues Heap-Limit noch nicht gefunden, aber ich habe gerade eine JVM mit einer Heap-Größe von 5900 m geöffnet . Kein Problem!

Ich verwende Win 7 64-Bit Ultimate auf einem Computer mit 24 GB RAM.

user1652651
quelle
0

Ich habe versucht, die Heap-Größe auf einem 32-Bit-Linux-Computer auf 2200 MB einzustellen, und JVM hat einwandfrei funktioniert. Die JVM wurde nicht gestartet, als ich sie auf 2300M eingestellt habe.

Priya
quelle
Ich dachte, ich würde hinzufügen, dass unter Windows VISTA 64-Bit eine 32-Bit-JVM mit maximal 1582 m (-Xmx-Wert) maximal ist. Es wird sich beschweren, wenn ich 1583m spezifiziere. Ich weiß nicht, ob sich dieser Wert von Maschine zu Maschine ändert. Der Computer, auf dem ich dies getestet habe, hatte tatsächlich 4 GB physischen RAM.
Santosh Tiwari
@ SantoshTiwari es ändert sich von Maschine zu Maschine, aber hier ist der Grund
Eugene
0

Ein weiterer Punkt hier für Hotspot-32-Bit-JVM: - Die native Heap-Kapazität = 4 Gig - Java-Heap - PermGen;

Für 32-Bit-JVM kann es besonders schwierig werden, da sich der Java-Heap und der native Heap in einem Rennen befinden. Je größer Ihr Java-Heap ist, desto kleiner ist der native Heap. Der Versuch, einen großen Heap für eine 32-Bit-VM einzurichten, z. B. 2,5 GB +, erhöht das Risiko eines nativen OutOfMemoryError in Abhängigkeit von der Größe Ihrer Anwendung (en), der Anzahl der Threads usw.

ajay29
quelle
0

Die Einschränkung ergibt sich auch aus der Tatsache, dass für eine 32 bitVM die heapAdresse selbst bei Adresse Null beginnen muss, wenn Sie alle diese möchten 4GB.

Denken Sie darüber nach, wenn Sie etwas referenzieren möchten über:

0000....0001

Das heißt: Eine Referenz mit dieser speziellen Bitdarstellung bedeutet, dass Sie versuchen, vom Heap aus auf den allerersten Speicher zuzugreifen. Damit dies möglich ist, muss der Heap bei Adresse Null beginnen. Aber das passiert nie, es beginnt bei einem Versatz von Null:

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

Da der Heap in einer niemals mit der Adresse Null beginnt OS, gibt es einige Bits, die niemals aus einer 32Bitreferenz verwendet werden, und als solche ist der Heap, auf den verwiesen werden kann, niedriger.

Eugene
quelle
-1

Theoretische 4 GB, aber in der Praxis (für 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 32-Bit

[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
quelle