Was macht das UseCompressedOops JVM-Flag und wann sollte ich es verwenden?

84

Was macht das HotSpot JVM-Flag -XX:+UseCompressedOopsund wann sollte ich es verwenden? Welche Unterschiede in Bezug auf Leistung und Speichernutzung sehe ich, wenn ich es auf einer 64-Bit-Java-Instanz verwende (anstatt es nicht zu verwenden)?

noahlz
quelle
1
Es komprimiert 64-Bit-Zeiger. Sie werden feststellen, dass sich der Speicher aufgrund der vergrößerten Zeigergröße verringert, weniger Zeit für die GC aufgewendet wird und möglicherweise die Leistung geringfügig abnimmt. jdk1.6.0_22 war die letzte Sun JVM, bei der dieses Flag standardmäßig deaktiviert war.
Sjr

Antworten:

85

Die meisten HotSpot JVM im letzten Jahr haben es standardmäßig aktiviert. Mit dieser Option können Referenzen in einer 64-Bit-JVM 32-Bit sein und auf fast 32 GB Heap zugreifen. (mehr als 32-Bit-Zeiger können) (Sie können auch nahezu unbegrenzten Off-Heap-Speicher haben). Dies kann eine erhebliche Menge an Speicher sparen und möglicherweise die Leistung verbessern.

Wenn Sie diese Option verwenden möchten, empfehlen wir Ihnen, auf eine Version zu aktualisieren, auf der sie standardmäßig aktiviert ist, da es möglicherweise einen guten Grund gab, z. B. Fehler, warum sie zuvor nicht aktiviert wurde. Versuchen Sie Java 6 Update 23 oder Java 7 Update 5.

Kurz gesagt, schalten Sie es nicht ein, sondern verwenden Sie eine Version, in der es standardmäßig aktiviert ist.


Aktualisieren:

In Java 8 haben Sie die Möglichkeit, das -XX:ObjectAlignmentInBytes=festzulegen. Wenn Sie die Heap-Größe auf 64 GB festlegen , werden -XX:ObjectAlignmentInBytes=1632-Bit-Referenzen verwendet und weiterhin verwendet.

Peter Lawrey
quelle
Ich habe diesen Artikel gelesen: community.oracle.com/message/10019916, der besagt, dass wir dieses Flag immer manuell verwenden sollten, auch wenn es standardmäßig aktiviert ist. Irgendwelche Gedanken?
Vanval
1
@vanval JE cache Dies wird empfohlen, wenn Sie verwenden. Dies liegt daran, dass nicht herausgefunden werden kann, ob Sie Komprimierungen verwenden. Hoppla oder nicht. Ich kann mir ein paar Methoden vorstellen, die Ihnen das übrigens sagen können. Sie sollten es IMHO nicht in der Befehlszeile angeben müssen, es sei denn, Sie möchten, dass die JVM fehlschlägt, wenn sie nicht aktiviert ist. Beispiel: Sie haben einen 64-GB-Heap auf Java 8.
Peter Lawrey
3
Ich habe gerade einige Tests auf Win8 x64 i7-4702MQ JDK 8 u40 mit 7 GB xms und xmx durchgeführt. Von 7 GB werden 5,4 GB von einem großen Baum verwendet, der von einer Access-Datenbank geladen wurde. Mein Punkt ist: Die manuelle Angabe des Flags -XX: + UseCompressedOops führt zu einer Leistungsminderung von 20% (beim Generieren des großen Baums) und einer weiteren (von 3 auf 4) langen GC-Pause (mit Standard-GC). Sie nehmen es entweder als Leistungsabfall oder als Erhöhung der GC-Pause. In beiden Fällen war es 20% langsamer.
Zmirc
1
Jede Anwendung verfügt über ein eigenes Speicher- und Nutzungsprofil. In unserem Fall spart eine Desktop-App mit 32-Bit-JVM und dem Flag + UseCompressedOops den Tag, da die Speichernutzung so niedrig gehalten wurde, dass sie auf den alten 4-GB-Computer des Clients passt, und die Leistung im Vergleich zu 32-Bit-JVM um 30% gesteigert wurde.
Alex Byrth