2011-09-22 18 views
71

Czy ktoś może wyjaśnić, czym są opcje JVM ReservedCodeCacheSize i InitialCodeCacheSize? W szczególności kiedy/dlaczego chciałbym to zmienić? Jak mogę zdecydować, jaki jest właściwy rozmiar?Co to są ReservedCodeCacheSize i InitialCodeCacheSize?

To co docs powiedzieć:

-XX: ReservedCodeCacheSize = 32m Reserved rozmiar kodu cache (w bajtach) - maksymalna wielkość kodu cache. [Solaris 64-bit, amd64 i -server x86: 2048m; w 1.5.0_06 i wcześniej, Solaris 64-bit i and64. 1024m]

+2

OP tego wpisu napisał:> -XX: ReservedCodeCacheSize = 32m Zarezerwowany rozmiar pamięci podręcznej kodu (w bajtach) - maksymalny rozmiar pamięci podręcznej kodu. [Solaris 64-bit, amd64 i -server x86: 48m; w wersji 1.5.0_06 i wcześniejszych, Solaris 64-bit i and64: 1024m.] Chcę tylko poprawić, że wspomniany górny limit na 48m musi być literówką. To 2048m. –

Odpowiedz

66

ReservedCodeCacheSize (i InitialCodeCacheSize) jest opcją dla (just-in-time) kompilatora Java Hotspot VM. Zasadniczo ustawia maksymalny rozmiar pamięci podręcznej kodu kompilatora.

Pamięć podręczna może się zapełnić, co powoduje ostrzeżeń, jak następuje:

Java HotSpot(TM) 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled. 
Java HotSpot(TM) 64-Bit Server VM warning: Try increasing the code cache size using -XX:ReservedCodeCacheSize= 
Code Cache [0x000000010958f000, 0x000000010c52f000, 0x000000010c58f000) 
total_blobs=15406 nmethods=14989 adapters=362 free_code_cache=835Kb largest_free_block=449792 

Jest znacznie gorzej, gdy następuje Java HotSpot(TM) Client VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated.

Kiedy ustawić tę opcję?

  1. gdy o awarii Hotspot kompilatora
  2. zmniejszenie pamięci potrzebnej JVM (a tym samym ryzykując awarie kompilatora JIT)

Zwykle nie chcesz zmienić tę wartość. Myślę, że wartości domyślne są dość dobrze zrównoważone, ponieważ problemy te występują tylko w bardzo rzadkich przypadkach (w moim doświadczeniu).

+1

Nice. Jakie są domyślne wartości i do czego powinny zostać zwiększone, jeśli widzimy "CodeCache jest pełny". ostrzeżenie? – axel22

+2

@ axel22: Wartości zależą od platformy i wersji JVM; wartości z dokumentu dla Sun JVM: 'Zarezerwowany rozmiar pamięci podręcznej kodu (w bajtach) - maksymalny rozmiar pamięci podręcznej kodu. [Solaris 64-bit, amd64 i -server x86: 48m; w wersji 1.5.0_06 i wcześniejszych, Solaris 64-bit i amd64: 1024m.] 'Nie zna wartości OpenJDK. Umiarkowany wzrost powinien wystarczyć (wcześniejsze ustawienie 1024 m wykracza poza dobro i zło). – jeha

12

@jeha odpowiada na wszystko, co chciałem wiedzieć na podstawie tego pytania, poza tym, do jakiej wartości należy ustawić parametry. Ponieważ nie napisałem kodu, który wdrażałem, nie miałem zbyt dużego wglądu w jego ślad pamięci.

Można jednak użyć jconsole do przyłączenia się do uruchomionego procesu java, a następnie użyć karty "Pamięć", aby sprawdzić rozmiar pamięci podręcznej kodu. Dla kompletności, kroki są (środowisko Linux VM, choć jestem pewien, że inne środowiska są podobne):

  1. odpalić JConsole na komputerze
  2. Znajdź odpowiedni identyfikator procesu i dołączyć do niego JConsole (ta wola potrwać kilka chwil)
  3. Przejdź do „pamięci” karcie
  4. z „wykresu:” rozwijanej listy wybierz „puli pamięci«Code Cache»”
  5. Znowu, może to potrwać kilka chwil Aby ekran się odświeżył, a następnie powinieneś zobaczyć coś takiego: jconsole code cache image

    Jak widać, moja pamięć podręczna kodu zużywa około 49 MB. W tym momencie nadal miałem domyślne ustawienie, które dokumentuje (i @jeha) 48 MB. Z pewnością jest to dla mnie wspaniała motywacja do zwiększenia ustawienia!

    Ben.


    1024 MB domyślnie prawdopodobnie było przesadzone, ale domyślnie 48 MB wydaje się niedo ...

+0

Dobra sugestia .... Próbuję z -J-XX: ReservedCodeCacheSize = 512m – MarcoZen

+0

Netbeans nie zacząłby się od 512m, zrobiłem z 256m – MarcoZen

+0

I po testach przez około 2 dni mogę powiedzieć, że ustawienie nie pokazało żadnych/żadnych zauważalna poprawa i zamiast tego sprawił, że netbeans był podchmielony. Skończyło się po prostu usunięcie go. – MarcoZen

11

Kiedy JVM kompiluje kod, to posiada zestaw instrukcji montażu-językowe w pamięci podręcznej kodu . Pamięć podręczna kodu ma stały rozmiar, a po jej wypełnieniu JVM nie jest w stanie skompilować żadnego dodatkowego kodu.

Maksymalny rozmiar pamięci podręcznej kodów ustawiany jest za pomocą opcji -XX: ReservedCodeCacheSize = N flag (gdzie N jest domyślną wzmianką o konkretnym kompilatorze). Pamięć podręczna kodu to zarządzana jak większość pamięci w JVM: istnieje początkowy rozmiar ( -XX: InitialCodeCacheSize = N). Przydział rozmiaru pamięci podręcznej kodu rozpoczyna się od początkowego rozmiaru i zwiększa się w miarę zapełniania pamięci podręcznej. Początkowy rozmiar pamięci podręcznej kodu różni się w zależności od architektury układu i używanego kompilatora w oparciu o architekturę. Zmiana rozmiaru pamięci podręcznej odbywa się w tle i tak naprawdę nie wpływa na wydajność, dlatego ustawienie rozmiaru ReservedCodeCacheSize (tj. Ustawienie maksymalnego rozmiaru pamięci podręcznej kodu) jest ogólnie potrzebne.

Domyślnie dla serwera 64-bitowego rozmiar Java 7 wynosi 48 MB (z warstwową kompilacją 96 MB). W języku Java 8 dla serwera 64-bitowego rozmiar pamięci wynosi 240 MB.

- Pinaki

+2

+1 za podanie różnicy wielkości Java 7/Java 8. Podejrzewam, że tak jest, ponieważ warstwowa kompilacja jest domyślnie włączona w Javie 8. – jdv

+0

Masz rację, wielopoziomowa kompilacja została ustabilizowana po 1.7.40, zanim pojawią się pewne problemy. Warstwowa kompilacja może z łatwością wykorzystać całą pamięć podręczną kodu w domyślnej konfiguracji, dzięki czemu zwiększyły ją do bezpieczniejszego poziomu w Java8. –

1

To dobre doświadczenie uczenia się od Rzeczywiście zespół inżynierów i wyzwaniami stanęli przy migracji do JDK 8.

http://engineering.indeedblog.com/blog/2016/09/job-search-web-app-java-8-migration/

Wnioski: JDK 8 potrzebuje więcej pamięci podręcznej kodu han JDK 7

Domyślny rozmiar kodeków dla JRE 8 wynosi około 250 MB, około pięć razy więcej niż 48 MB domyślnie dla środowiska JRE 7. Z doświadczenia wiemy, że środowisko JRE 8 wymaga tego dodatkowego kodeku. Do tej pory zmieniliśmy około dziesięciu usług na JRE 8, a wszystkie z nich używają około cztery razy więcej kodeków niż wcześniej.

0

z https://blogs.oracle.com/poonam/entry/why_do_i_get_message:

Poniżej znajdują się dwa znane problemy w jdk7u4 + w odniesieniu do spłukiwania CodeCache:

  1. Kompilator nie może się ponownie uruchomić nawet po obłożeniu CodeCache spada do prawie połowę po awaryjnym zaczerwienieniu.
  2. Płukanie awaryjne może spowodować wysokie użycie procesora przez wątki kompilatora, co prowadzi do ogólnego pogorszenia wydajności.

Ten problem z wydajnością i problem z ponownym włączeniem kompilatora został rozwiązany w JDK8. Aby obejść je w JDK7u4 +, możemy zwiększyć rozmiar pamięci podręcznej kodu przy użyciu opcji ReservedCodeCacheSize, ustawiając ją na wartość większą niż ślad kodu skompilowanego kodu, aby CodeCache nigdy się nie zapełnił. Innym rozwiązaniem jest wyłączenie funkcji CodeCache Flushing za pomocą opcji JVM -XX: -UseCodeCacheFlushing.

Powyższe problemy zostały naprawione w JDK8 i jego aktualizacjach.

Taka informacja może być warta wspomnienia dla systemów działających na JDK 6 (z wyłączonym opróżnianiem kodu) i 7.