Java "Konnte nicht genügend Speicherplatz für Objekthaufen reservieren", obwohl genügend RAM vorhanden ist

8

Ich habe derzeit einige Probleme mit Java. Es wird aufgrund von Heap-Problemen nicht gestartet. Aber ich habe mehr als 9 GB RAM frei (oder sogar 16 GB, wenn Sie davon ausgehen, dass der Cache leer ist). Dies ist der Fehler, den ich bekomme (und der freeBefehl)

root@server: ~ # java
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.

root@server: ~ # free
             total       used       free     shared    buffers     cached
Mem:      25165824   15941148    9224676          0          0    7082176
-/+ buffers/cache:    8858972   16306852
Swap:            0          0          0

Ich verwende ein 64-Bit-Debian auf einem virtualisierten Server. Die Virtualisierungssoftware ist OpenVZ. Dies ist meine Java-Version (ich kann diesen Befehl ausführen, nachdem ich zwei meiner VMs gestoppt habe (4 laufen derzeit)) :

root@server: ~ # java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

Was könnte ich tuen?


Wie gewünscht:

root@server: ~ # cat /proc/meminfo
MemTotal:       25165824 kB
MemFree:        11723412 kB
Cached:          4597552 kB
Active:          9692308 kB
Inactive:        3322544 kB
Active(anon):    7411960 kB
Inactive(anon):  1005340 kB
Active(file):    2280348 kB
Inactive(file):  2317204 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:               960 kB
Writeback:             0 kB
AnonPages:       8417300 kB
Shmem:             21504 kB
Slab:             427452 kB
SReclaimable:     383424 kB
SUnreclaim:        44028 kB

Reguest2:

root@server: ~ # cat /proc/user_beancounters
Version: 2.5
       uid  resource                     held              maxheld              barrier                limit              failcnt
 10023468:  kmemsize                399250512            506245120           5053325720           5558658292                    0
            lockedpages                     0                    8               246744               246744                    0
            privvmpages               6005602              6291447              6291456              6291456                  221
            shmpages                     8576                 8608               579124         579124289562                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            numproc                       598                 1236                30000                30000                    0
            physpages                 4634494              6291456              6291456              6291456                    0
            vmguarpages                     0                    0              6291456  9223372036854775807                    0
            oomguarpages              1529371              2144671              6291456  9223372036854775807                    0
            numtcpsock                     62                  164                30000                30000                    0
            numflock                       25                   39                 1000                 1100                    0
            numpty                         13                   24                  512                  512                    0
            numsiginfo                     10                   75                 1024                 1024                    0
            tcpsndbuf                 3330352              4153232           1179110194           1684441906                    0
            tcprcvbuf                 1216896             34410032           1179110194           1684441906                    0
            othersockbuf               270504               537552            589555096           1094886808                    0
            dgramrcvbuf                     0                67048            589555096            589555096                    0
            numothersock                  287                  333                30000                30000                    0
            dcachesize              355559855            446054103           1103879952           1136996352                    0
            numfile                      4766                 7745               250000               250000                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            numiptent                      14                   14                 1000                 1000                    0

root@server: ~ # java
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.

root@server: ~ # cat /proc/user_beancounters
Version: 2.5
       uid  resource                     held              maxheld              barrier                limit              failcnt
 10023468:  kmemsize                399246622            506245120           5053325720           5558658292                    0
            lockedpages                     0                    8               246744               246744                    0
            privvmpages               6005601              6291447              6291456              6291456                  233
            shmpages                     8576                 8608               579124         579124289562                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            numproc                       598                 1236                30000                30000                    0
            physpages                 4635460              6291456              6291456              6291456                    0
            vmguarpages                     0                    0              6291456  9223372036854775807                    0
            oomguarpages              1529376              2144671              6291456  9223372036854775807                    0
            numtcpsock                     64                  164                30000                30000                    0
            numflock                       25                   39                 1000                 1100                    0
            numpty                         13                   24                  512                  512                    0
            numsiginfo                     10                   75                 1024                 1024                    0
            tcpsndbuf                 3365232              4153232           1179110194           1684441906                    0
            tcprcvbuf                 1249664             34410032           1179110194           1684441906                    0
            othersockbuf               270504               537552            589555096           1094886808                    0
            dgramrcvbuf                     0                67048            589555096            589555096                    0
            numothersock                  287                  333                30000                30000                    0
            dcachesize              355559855            446054103           1103879952           1136996352                    0
            numfile                      4768                 7745               250000               250000                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            dummy                           0                    0  9223372036854775807  9223372036854775807                    0
            numiptent                      14                   14                 1000                 1000                    0
BrainStone
quelle
Können Siecat /proc/meminfo
Matt
@mindthemonkey Beitrag bearbeitet. Mir scheint, dass genügend Platz für die Standardgröße vorhanden ist.
BrainStone
Sieht auf jeden Fall so aus =) Sie versuchen, den Java-Prozess im Container auszuführen, oder? Ich gehe davon aus, dass Sie den Java-Prozess auf dem Host erfolgreich ausführen können. Wie viel Speicher ist jedem Container zugeordnet vzmemcheck -vA? Können Sie cat /proc/user-beancountervor und nach dem Fehler.
Matt
@mindthemonkey Ich habe keinen Zugang zu etwas außerhalb des Containers ...
BrainStone
ok .. cat /proc/user-beancounterist in deinem Container erledigt.
Matt

Antworten:

10

OpenVZ & Speicher

Das failcntläuft privvmpages, sodass Ihr Container keinen virtuellen Speicherplatz mehr vom Host zuweisen kann:

root@server: ~ # cat /proc/user_beancounters
Version: 2.5
       uid  resource                     held              maxheld              barrier                limit              failcnt
            privvmpages               6005601              6291447              6291456              6291456                 >233<
            physpages                 4635460              6291456              6291456              6291456                    0
            vmguarpages                     0                    0              6291456  9223372036854775807                    0
            oomguarpages              1529376              2144671              6291456  9223372036854775807                    0

Beachten Sie, dass virtueller Speicher ! = Physischer Speicher. Prozesse können zuweisen (- 4G, 64 - Bit - 8 TB - 256 TB 32bit ~ 2G) , aber das bedeutet nicht , physische Speicherseiten verwendet werden (eine Seite ein 4 - KB - Teil des Speichers ist) um die adressierbaren Größe des virtuellen Speichers bis zu irgendwo.

physpagesist die Anzahl der physischen Speicherseiten, die Ihr Container verwenden kann.
oomguarpagesist die garantierte Speicherseite, die der Container erhält, wenn der Host über einen eingeschränkten Speicher verfügt.
privvmpagesIst die Anzahl der virtuellen Speicherseiten, die Ihr Container verwenden kann,
vmguarpagesist die garantierte Menge an virtuellem Speicher auf die gleiche Weise

Java

Oracle Java weist immer einen zusammenhängenden Teil des virtuellen Speichers zu. Wenn Sie javakeine Argumente für eine Box RSSausführen, werden 5 MB realer Speicher verwendet ( ), aber 660 MB VM-Speicherplatz zugewiesen ( VSZ):

  PID COMMAND                        VSZ   RSS
20816 java                        667496  4912 

Wenn Sie sich die Speichersegmente für den javaProzess in der smapsDatei ansehen, wird ein Teil von ca. 500 MB zugewiesen. Der Rest sind Dateien mit Speicherzuordnung und normales Java-Material.

Auf einem System, das schon länger aktiv ist, wird der verfügbare VM-Speicherplatz fragmentiert, wenn Prozesse Teile davon verwenden / freigeben. A grep Vmalloc /proc/meminfogibt Ihnen VmallocChunkden größten derzeit verfügbaren kostenlosen Block. Wenn dies niedrig ist, versucht das System, auf Anfrage mehr zuzuweisen java, schließlich ist es auf einer 64-Bit-Box praktisch unbegrenzt.

Fix

Sagen Sie Ihrem Host, er soll konfigurieren privvmpagesund vmguarpagesviel höher. Sie müssen nicht mit dem physischen Speicher identisch sein, da dies die Funktionsweise des Linux-Speichers beeinflusst

Möglicherweise können Sie das Problem vorübergehend umgehen, indem Sie den Datei-Cache löschen. Dies ist echo 1 > /proc/sys/vm/drop_cachesjedoch nur vorübergehend.

Sie können den Speicherbereich java, der zur Laufzeit zugewiesen werden soll, auf ein Minimum Xmsoder während der Ausführung auf ein Maximum beschränken Xmx. Laufen javamit diesen Optionen auf meinem Computer:

java -Xms10M -Xmx10M

Reduziert die virtuelle Gesamtgröße auf ca. 140 MB, wobei nur ein zusammenhängender Block von 10 MB für den zugewiesenen Java-Heap zugewiesen wird.

Matt
quelle
Vielen Dank für Ihre Antwort. Ich bin zu 100% sicher, dass mein Hoster nichts an dem Container ändern wird. Ich kann meinen Cache auch nicht löschen, da sich mein Container in OpenVZ befindet. (Gibt zusätzlich grep Vmalloc /proc/meminfokeine Ausgabe) Laufen java -Xms10M -Xmx10Mfunktioniert aber. Dies löst jedoch nicht wirklich alle Probleme. Als würde man zusätzliche Programme mit einer RAM-Auslastung von etwa 2 GB starten ...
BrainStone
Warum verwenden Sie sie, wenn Sie nicht glauben, dass ihre Unterstützung Ihnen bei einem Konfigurationsproblem nicht helfen würde? Vielleicht Website der Konfigurationsbeispiele und Tabellen ? Es kostet sie nichts, zusätzliche unbrauchbare Speicherseiten zuzuweisen.
Matt
Ich benutze sie, weil die Qualität ausreicht und der Preis niedrig ist. Zweitens gibt es eine Möglichkeit, Java mitzuteilen, dass keine kontinuierlichen Speicherblöcke verwendet werden sollen?
BrainStone
@BrainStone Sie führen eine 64-Bit-JVM aus. Die Fragmentierungsbeschränkung sollte nur 32-Bit-Anwendungen auf einem 32-Bit-Betriebssystem betreffen.
Jlliagre
@jlliagre openvz begrenzt den VM-Speicherplatz künstlich.
Matt
7

In unserem Fall hat es geholfen, die Heap-Größe zu beschränken, die die VM beim Start zu reservieren versucht.

Zum Beispiel in der Kommandozeile:

export _JAVA_OPTIONS = '- Xms64M -Xmx128m'

oder für Tomcat in [TOMCAT_HOME] /bin/setenv.sh

#! / bin / sh

JAVA_OPTS = "- Xms64M -Xmx256M"

(Beachten Sie den zusätzlichen führenden Unterstrich in der Befehlszeile.)

Die Erklärung unseres Anbieters lautet:

  • Die Java-VM berechnet beim Start eine anfängliche Heap-Größe
  • Diese Berechnung basiert auf dem verfügbaren RAM.
  • Einige Java-Installationen auf Virtual Private Servern (VPS) berücksichtigen bei der Berechnung der anfänglichen Heap-Größe nicht die Speicherbeschränkungen des VPS. Stattdessen stützen sie ihre Berechnung auf die Speichergröße des Hosting-Systems. Dies kann zu einer Menge an freiem Speicher führen, die auf dem VPS nicht verfügbar ist.
  • Bei der Bereitstellung einer anfänglichen Heap-Größe über JAVA_OPTS verwendet die VM diese Werte und versucht nicht, diese selbst zu berechnen.
c_froehlich
quelle
Dies hat mein Problem behoben. Ich war nicht auf einem virtuellen Server, sondern auf Hardware mit 80 GB RAM. Der Server ist neu und wird noch nicht verwendet, sodass der gesamte Speicher verfügbar war. Das Standard-Systemspeicherlimit von 16 GB hat dazu geführt, dass ich die JVM nicht starten konnte. Auch als Wurzel. Durch Ändern von /etc/security/limits.conf wurde das Problem behoben. RHEL6.6.
Dan Pritts
3

Möglicherweise müssen Sie die Standardgröße des Java-Heaps ändern. Probieren Sie die folgenden Argumente aus:

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        set java thread stack size

zum Beispiel:

java -Xms64m -Xmx1512m

Dieser Thread könnte hilfreich sein

Überprüfen Sie auch das ulimit (ulimit bietet Kontrolle über die Ressourcen, die der Shell und den von ihr gestarteten Prozessen zur Verfügung stehen):

ulimit -a 
b13n1u
quelle
Ich verwende bereits die Argumente für die Heap-Größe (beim Starten von Anwendungen). Und mein ulimit -ascheint normal. Die meisten Werte einschließlich virtual memorysind unbegrenzt. Diejenigen, die ein wenig niedrig schienen, habe ich zum Testen verdoppelt ( -svon 8192 auf 16384 und -lvon 64 auf 128) , aber das hat auch nicht geholfen.
BrainStone
Und was ist mit der Adressraumgröße für den Prozess (-A)? Eine weitere Sache, es sieht so aus, als hätten Sie überhaupt keinen Swap Space. Das ist wirklich nicht gut, da Swap auch die Größe Ihres virtuellen Speichers erhöht. Java versucht, den Speicher in einem großen Block zuzuweisen, sodass das Betriebssystem möglicherweise versucht, nicht verwendeten Speicher für den Austausch neu zuzuweisen. Bitte versuchen Sie, 32 GB Swap hinzuzufügen.
b13n1u
Es gibt keine -AOption für mich. Und ich darf Swap nicht hinzufügen.
BrainStone
2

Möglicherweise haben Sie nicht genügend virtuellen Speicher.

Sie konzentrieren sich auf die RAM-Nutzung (oder auf das Fehlen), aber Ihre vorhandenen JVMs reservieren virtuellen Speicher, nicht RAM. Solange nicht auf reservierte Speicherseiten zugegriffen wird, wird für sie keine RAM-Auslastung gemeldet.

Während Linux dieses Problem normalerweise durch seine Einstellungen für die Überbindung maskiert, ist es durchaus möglich, dass die Tatsache, dass Sie in einer virtualisierten Umgebung auf Betriebssystemebene ausgeführt werden, die Überbindung entweder verringert / deaktiviert oder eine Begrenzung der Ressourcensteuerung für den virtuellen Speicher festlegt.

Auf einer normalen Betriebssysteminstanz (kein Container) können Sie dies am einfachsten umgehen, indem Sie einen Swap hinzufügen, damit der reservierte Speicher keinen RAM verschwendet. Bei einem Container kann zur Behebung des Problems möglicherweise auch der global verfügbare virtuelle Speicher erhöht werden. Im Allgemeinen wird dem Container jedoch einfach mehr virtueller Speicher zugewiesen.

jlliagre
quelle