Co robi flaga UseCompressedOops JVM i kiedy należy jej używać?

85

Co robi flaga HotSpot JVM -XX:+UseCompressedOopsi kiedy należy jej używać? Jakie różnice w wydajności i wykorzystaniu pamięci zobaczę podczas korzystania z niej w 64-bitowej instancji Java (w porównaniu z jej nieużywaniem)?

noahlz
źródło
1
Kompresuje wskaźniki 64-bitowe. Zobaczysz zmniejszone rozdęcie pamięci spowodowane zwiększonym rozmiarem wskaźnika, krótszym czasem spędzonym w GC, być może niewielkim spadkiem wydajności. jdk1.6.0_22 była ostatnią maszyną JVM firmy Sun, dla której ta flaga jest domyślnie wyłączona.
sjr

Odpowiedzi:

86

Większość JVM HotSpot w zeszłym roku miała ją domyślnie włączoną. Ta opcja umożliwia 32-bitowe odwołania w 64-bitowej maszynie JVM i dostęp do sterty blisko 32 GB. (więcej niż 32-bitowe wskaźniki) (Możesz również mieć prawie nieograniczoną pamięć poza stertą). Może to zaoszczędzić znaczną ilość pamięci i potencjalnie poprawić wydajność.

Jeśli chcesz skorzystać z tej opcji, sugeruję aktualizację do wersji, która ma ją domyślnie włączoną, ponieważ mógł istnieć dobry powód, taki jak błędy, dlaczego wcześniej nie była włączona. Wypróbuj aktualizację Java 6 Update 23 lub Java 7 Update 5.

Krótko mówiąc, nie włączaj go, użyj wersji, która ma to domyślnie.


Aktualizacja:

W Javie 8 masz opcję ustawienia -XX:ObjectAlignmentInBytes=i faktycznie, jeśli rozmiar sterty wynosi 64 GB, będzie on używał -XX:ObjectAlignmentInBytes=16i nadal będzie używał odwołań 32-bitowych.

Peter Lawrey
źródło
Czytałem ten artykuł: community.oracle.com/message/10019916, w którym stwierdza się, że zawsze powinniśmy używać tej flagi ręcznie, nawet jeśli jest ona domyślnie włączona. jakieś pomysły?
vanval
1
@vanval Jest to zalecane, jeśli używasz. JE cache Dzieje się tak, ponieważ z jakiegoś powodu nie można stwierdzić, czy używasz kompresji oops, czy nie. Przy okazji przychodzi mi do głowy kilka metod, które mogą ci to powiedzieć. Nie powinno być potrzeby określania tego w wierszu poleceń IMHO, chyba że chcesz, aby maszyna JVM uległa awarii, jeśli nie jest włączona. np. masz stertę 64 GB na Javie 8.
Peter Lawrey
3
Właśnie przeprowadziłem kilka testów na Win8 x64 i7-4702MQ JDK 8 u40 z 7 GB xms i xmx. Z 7 GB, 5,4 GB jest używane przez duże drzewo ładowane z bazy danych Access. Chodzi mi o to: ręczne określenie flagi -XX: + UseCompressedOops prowadzi do 20% spadku wydajności (podczas generowania dużego drzewa) i 1 więcej (od 3 do 4) długiej pauzy GC (z domyślnym GC). Możesz to potraktować jako spadek wydajności lub wzrost pauzy GC. Tak czy inaczej, był o 20% wolniejszy.
zmirc
1
Każda aplikacja ma własną pamięć i profil użytkowania. W naszym przypadku aplikacja komputerowa pochodząca z 32-bitowego jvm, flaga + UseCompressedOops uratowała sytuację, ponieważ utrzymywała zużycie pamięci na wystarczająco niskim poziomie, aby zmieścić się na starej maszynie 4 GB klienta i zwiększyła wydajność o 30% w porównaniu do 32-bitowego jvm.
Alex Byrth