Jak określa się domyślny maksymalny rozmiar sterty Java?

420

Jeśli pominę tę -Xmxnopcję w wierszu polecenia Java, zostanie użyta wartość domyślna. Według dokumentacji Java

„wartość domyślna jest wybierana w czasie wykonywania na podstawie konfiguracji systemu”

Jakie ustawienia konfiguracji systemu wpływają na wartość domyślną?

Richard Dorman
źródło
1
konfiguracja systemu oznacza: a) klient Jvm vs serwer Jvm b) 32bit vs 64bit. Linki: 1) aktualizacja z J2SE5.0 docs.oracle.com/javase/6/docs/technotes/guides/vm/… 2) krótka odpowiedź: docs.oracle.com/javase/8/docs/technotes/guides/vm / gctuning /… 3) szczegółowa odpowiedź: docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/… 4) klient kontra serwer: javacodegeeks.com/2011/07/jvm-options-client- vs-server.html
Vyshnav Ramesh Thrissur
2
ciężko to zrozumieć na podstawie powyższych linków. Podsumowując je tutaj: Maksymalny rozmiar sterty dla klienta Jvm wynosi 256 MB (istnieje wyjątek, odczytany z linków powyżej). Maksymalny rozmiar sterty dla serwera Jvm 32-bitowy to 1 gb, a 64-bitowy to 32 gb (znowu tutaj są też wyjątki. Przeczytaj to z linków). Więc jego 256
MB
Zobacz także stackoverflow.com/a/56036202/32453
rogerdpack

Odpowiedzi:

506

W systemie Windows można użyć następującego polecenia, aby dowiedzieć się o wartościach domyślnych w systemie, w którym działają aplikacje.

java -XX: + PrintFlagsFinal -version | findstr HeapSize

Poszukaj opcji MaxHeapSize(dla -Xmx) i InitialHeapSizedla -Xms.

W systemie Unix / Linux możesz to zrobić

java -XX: + PrintFlagsFinal -version | grep HeapSize

Uważam, że wynikowy wynik jest w bajtach.

kamienie333
źródło
3
Miałem nadzieję na taką fajną opcję, ale nie działało to dla mnie przy użyciu maszyny wirtualnej Java 6 IBM.
Matt Lavin,
Świetny! Czy mogę grać z tymi wszystkimi domyślnymi opcjami? Jaka jest odpowiednia zmienna ENV dla każdej z nich?
Elist
28
W moim przypadku na Linuksie, InitialHeapSize = 262803264a MaxHeapSize = 4206886912która wynosi około 256 MB i 4 GB , jeśli się nie mylę. Czy to oznacza, że ​​każda JVM zaczyna się tak, jakby była uruchamiana z -Xms256m -Xmx4gopcjami?
Yuriy Nakonechnyy
9
W systemie Windows:java -XX:+PrintFlagsFinal -version | findstr /R /C:"HeapSize"
sp00m
1
@matanster W moim systemie Linux -versionpomija długi tekst „użycia” na stderr.
Franklin Yu
115

Dla Java SE 5: Według Garbage Collector Ergonomics [Oracle] :

początkowy rozmiar sterty:

Większa 1/64 pamięci fizycznej urządzenia na maszynie lub rozsądne minimum. Przed J2SE 5.0 domyślna początkowa wielkość sterty była rozsądnym minimum, które różni się w zależności od platformy. Możesz zastąpić to ustawienie domyślne za pomocą opcji wiersza polecenia -Xms.

maksymalny rozmiar sterty:

Mniejszy z 1/4 pamięci fizycznej lub 1 GB. Przed J2SE 5.0 domyślny maksymalny rozmiar sterty wynosił 64 MB. Możesz zastąpić to ustawienie domyślne za pomocą opcji wiersza polecenia -Xmx.

AKTUALIZACJA:

Jak zauważył Tom Anderson w swoim komentarzu, powyższe dotyczy maszyn klasy serwerowej. Z ergonomii w maszynie wirtualnej Java 5.0 5.0 :

W platformie J2SE w wersji 5.0 klasa maszyny zwana maszyną klasy serwerowej została zdefiniowana jako maszyna z

  • 2 lub więcej procesorów fizycznych
  • 2 lub więcej GB pamięci fizycznej

z wyjątkiem 32-bitowych platform z wersją systemu operacyjnego Windows. Na wszystkich innych platformach wartości domyślne są takie same jak wartości domyślne dla wersji 1.4.2.

W platformie J2SE w wersji 1.4.2 domyślnie dokonano następujących wyborów

  • początkowy rozmiar sterty 4 MB
  • maksymalny rozmiar sterty 64 Mb
dogbane
źródło
4
Zastrzeżenie: dotyczy maszyn klasy serwerowej, a nie klasy klienta. Musisz przeczytać ten dokument w połączeniu z java.sun.com/docs/hotspot/gc5.0/ergo5.html, który definiuje te warunki i co dzieje się z komputerami klasy klienta. Dogbane, czy mogę pokornie zasugerować, aby zredagować swoją odpowiedź, aby zacytować odpowiednie fragmenty?
Tom Anderson
3
Jest to absurdalnie niska wartość domyślna w 2012 r. Bardzo niewiele poważnych aplikacji mieści się w 64 megabajtach.
Mark E. Haase
1
Zobacz odpowiedź Ernesto z 30 października 2012 r. Dla komputerów klienckich po aktualizacji Java 6 18.
Andy Thomas
Należy również pamiętać, że napisano: „Granice i ułamki podane dla wielkości sterty są poprawne dla J2SE 5.0. Prawdopodobnie będą się różnić w kolejnych wydaniach, ponieważ komputery stają się coraz potężniejsze”.
Lodovik
Nawiasem mówiąc, to algo jest tylko dla Parallel Garbage Collector.
Mike Argyriou
45

Java 8 trwa dłużej niż 1 / 64th swojej pamięci fizycznej dla Xmssize (minimalna HeapSize) i mniej niż 1/4 swojej fizycznej pamięci dla -Xmxsize (maksymalny HeapSize).

Możesz sprawdzić domyślny rozmiar sterty Java, wykonując:

W systemie Windows :

java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"

W systemie Linux :

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'

Jakie ustawienia konfiguracji systemu wpływają na wartość domyślną?

Maszyna znajduje się w pamięci fizycznej i wersja Java.

Sarat Chandra
źródło
5
czy to nie 1/64 zamiast 1/6?
Vyshnav Ramesh Thrissur
1
Tak Xmssize (Minimum HeapSize / InitialHeapSize) to ponad 1/64 pamięci fizycznej, a Xmxsize (Maximum HeapSize / MaxHeapSize) to mniej niż 1/4 pamięci fizycznej. (Na przykład dla mojego Maca, mając 16 GB pamięci RAM, otrzymuję uintx InitialHeapSize: = 268435456 {product} uintx MaxHeapSize: = 4294967296 {product}, tzn. Xms ma 268 MB, a Xmx wynosi 4,29 GB
sjethvani
1
Edytuj odpowiedź. Jest 1/64, a nie 1/6.
emeraldhieu
35

Zostało to zmienione w aktualizacji 18 Java 6 .

Zakładając, że mamy więcej niż 1 GB pamięci fizycznej (w dzisiejszych czasach dość powszechne), zawsze jest to jedna czwarta pamięci fizycznej dla serwera vm.

Ernesto
źródło
8
Niepoprawnie, na linkowanej stronie jest napisanegreater than or equal to 1 gigabyte of physical memory results in a maximum heap size of 256 megabytes
Paolo Fulgoni
5
Właśnie sprawdziłem na komputerze z systemem Linux z pamięcią fizyczną 5 GB. Domyślna maksymalna kupa ma wartość 1,5 gb
ernesto
1
@PaoloFulgoni nie, kolejny praktyczny przykład, który obserwuję teraz: 129 GB pamięci fizycznej skutkuje 32 GB maksymalnej wielkości sterty
Kirill
Zobacz odpowiedź apl, dlaczego tak jest: stackoverflow.com/a/13310792/32453 Zobacz także stackoverflow.com/a/56036202/32453
rogerdpack
16

Ernesto ma rację. Według linku, który opublikował [1]:

Zaktualizowana konfiguracja sterty JVM klienta

W JVM klienta ...

  • Domyślny maksymalny rozmiar sterty to połowa pamięci fizycznej do wielkości pamięci fizycznej wynoszącej 192 megabajty, a w przeciwnym razie jedna czwarta pamięci fizycznej do wielkości pamięci fizycznej wynoszącej 1 gigabajt.

    Na przykład, jeśli twoje urządzenie ma 128 megabajtów pamięci fizycznej, wówczas maksymalny rozmiar sterty wynosi 64 megabajty, a większy lub równy 1 gigabajt pamięci fizycznej daje maksymalny rozmiar sterty 256 megabajtów.

  • Maksymalna wielkość sterty nie jest faktycznie używana przez JVM, chyba że program utworzy wystarczającą liczbę obiektów, aby jej wymagać. Znacznie mniejsza ilość, zwana początkową wielkością sterty, jest przydzielana podczas inicjowania maszyny JVM. ...

  • ...
  • Ergonomia konfiguracji sterty JVM serwera jest teraz taka sama jak dla klienta, z tym że domyślny maksymalny rozmiar sterty dla 32-bitowych maszyn JVM wynosi 1 gigabajt , co odpowiada wielkości fizycznej pamięci 4 gigabajty, a dla 64-bitowej maszyny JVM wynosi 32 gigabajty , co odpowiada do fizycznej wielkości pamięci 128 gigabajtów.

[1] http://www.oracle.com/technetwork/java/javase/6u18-142093.html

apl
źródło
8

Wreszcie!

Od wersji Java 8u191 dostępne są teraz następujące opcje:

-XX:InitialRAMPercentage
-XX:MaxRAMPercentage
-XX:MinRAMPercentage

które mogą być użyte do ustalenia wielkości stosu jako procent użytecznej fizycznej pamięci RAM. (który jest taki sam, jak pamięć RAM zainstalowana mniej, niż używa jądro).

Aby uzyskać więcej informacji, zobacz Informacje o wersji Java8 u191 . Zauważ, że opcje są wymienione pod nagłówkiem Docker, ale w rzeczywistości mają zastosowanie niezależnie od tego, czy jesteś w środowisku Docker, czy w tradycyjnym środowisku.

Domyślna wartość MaxRAMPercentageto 25%. To jest bardzo konserwatywne.

Moja własna zasada: jeśli Twój host jest mniej więcej poświęcony uruchamianiu danej aplikacji Java, możesz bez problemu dramatycznie wzrosnąć. Jeśli korzystasz z systemu Linux, korzystasz tylko ze standardowych demonów i zainstalowałeś pamięć RAM od około 1 Gb i więcej, nie wahałbym się użyć 75% na stertę JVM. Ponownie pamiętaj, że jest to 75% dostępnej pamięci RAM , a nie zainstalowana pamięć RAM . Pozostały procesy lądowe innych użytkowników, które mogą być uruchomione na hoście, oraz inne rodzaje pamięci, których potrzebuje JVM (np. Do stosu). Ogólnie rzecz biorąc, będzie to zazwyczaj dobrze pasować w pozostałych 25%. Oczywiście przy jeszcze większej ilości zainstalowanej pamięci RAM 75% jest bezpieczniejszym wyborem. (Chciałbym, żeby ludzie z JDK wprowadzili opcję, w której można określić drabinę)

Ustawienie MaxRAMPercentageopcji wygląda następująco:

java -XX:MaxRAMPercentage=75.0  ....

Należy zauważyć, że te wartości procentowe są typu „podwójnego”, dlatego należy je podać kropką dziesiętną. Występuje nieco dziwny błąd, jeśli użyjesz „75” zamiast „75.0”.

Peter
źródło
7

wartość domyślna jest wybierana w czasie wykonywania na podstawie konfiguracji systemu

Zajrzyj na stronę dokumentacji

Domyślny rozmiar sterty

O ile początkowa i maksymalna wielkość sterty nie są określone w wierszu polecenia, są one obliczane na podstawie ilości pamięci na komputerze.

  1. Domyślne początkowe i maksymalne rozmiary stosu klienta JVM:

    Domyślny maksymalny rozmiar sterty to połowa pamięci fizycznej do wielkości pamięci fizycznej wynoszącej 192 megabajty (MB), a poza tym jedna czwarta pamięci fizycznej do wielkości pamięci fizycznej wynoszącej 1 gigabajt (GB) .

  2. Domyślne początkowe i maksymalne rozmiary sterty serwera JVM:

    W 32-bitowych maszynach JVM domyślny maksymalny rozmiar sterty może wynosić do 1 GB, jeśli jest 4 GB lub więcej pamięci fizycznej . W 64-bitowych maszynach JVM domyślny maksymalny rozmiar sterty może wynosić do 32 GB, jeśli jest 128 GB lub więcej pamięci fizycznej

Jakie ustawienia konfiguracji systemu wpływają na wartość domyślną?

Możesz określić początkową i maksymalną wielkość sterty, używając flag -Xms (początkowy rozmiar sterty) i -Xmx (maksymalny rozmiar sterty). Jeśli wiesz, ile sterty musi działać twoja aplikacja, możesz ustawić -Xms i -Xmx na tę samą wartość

Ravindra babu
źródło
5

Flaga Xmsi Xmxsą flagą wirtualnej maszyny Java (JVM):

  • Xms: initial and minimumJVMheap size
    • Format: -Xmx<size>[g|G|m|M|k|K]
    • Default Size:
      • -server tryb: 25% wolnej pamięci fizycznej,> = 8 MB i <= 64 MB
      • -client mode: 25% wolnej pamięci fizycznej,> = 8 MB i <= 16 MB
    • Typical Size:
      • -Xms128M
      • -Xms256M
      • -Xms512M
    • Function/ Effect:
      • -> JVM start z alokacją Xmspamięci wielkości
  • Xmx: maximumJVMheap size
    • Format: -Xmx<size>[g|G|m|M|k|K]
    • Default Size:
      • <= R27.2
        • Windows: 75%całkowitej pamięci fizycznej do1GB
        • Linux/Solaris: 50%dostępnej pamięci fizycznej do1GB
      • >= R27.3
        • Windows X64: 75%całkowitej pamięci fizycznej do2GB
        • Linux/Solaris X64: 50%dostępnej pamięci fizycznej do2GB
        • Windows x86: 75%całkowitej pamięci fizycznej do1GB
        • Linux/Solaris X86: 50%dostępnej pamięci fizycznej do1GB
    • Typical Size:
      • -Xmx1g
      • -Xmx2084M
      • -Xmx4g
      • -Xmx6g
      • -Xmx8g
    • Function/ Effect:
      • -> JVM pozwala na użycie maksimum Xmxpamięci wielkości
        • kiedy przekroczy Xmx, będziejava.lang.OutOfMemoryError
          • Jak to naprawić OutOfMemoryError?
            • przekraczać Xmxwartość
              • np .: od -Xmx4gdo-Xmx8g

Więcej szczegółów

zobacz oficjalny dokument: -X Opcje wiersza polecenia

Crifan
źródło
Czy to nie jest JVock JRockit? (w przeciwieństwie do JVM Hotspot Oracle)
peterh
4

Wiele parametrów wpływa na wielkość generacji. Poniższy diagram ilustruje różnicę między zatwierdzoną przestrzenią a przestrzenią wirtualną w stercie. Podczas inicjowania maszyny wirtualnej zarezerwowane jest całe miejsce na sterty. Rozmiar zarezerwowanego miejsca można określić za pomocą -Xmxopcji. Jeśli wartość -Xmsparametru jest mniejsza niż wartość -Xmxparametru, nie cała zarezerwowana przestrzeń jest natychmiast przydzielana do maszyny wirtualnej. Na tym rysunku nieprzydzielone miejsce jest oznaczone jako „wirtualne”. Różne części sterty (generacja stała, generacja najemna i generacja młoda) mogą w razie potrzeby wzrosnąć do granicy przestrzeni wirtualnej.

wprowadź opis zdjęcia tutaj

Domyślnie maszyna wirtualna powiększa lub zmniejsza stertę w każdej kolekcji, aby utrzymać proporcję wolnej przestrzeni dla obiektów aktywnych w każdej kolekcji w określonym zakresie. Ten zakres docelowy jest ustalany procentowo przez parametry - XX:MinHeapFreeRatio=<minimum>i -XX:MaxHeapFreeRatio=<maximum>, a całkowity rozmiar jest ograniczony poniżej -Xms<min>i powyżej przez -Xmx<max>.

Parametr Wartość domyślna

MinHeapFreeRatio 40

MaxHeapFreeRatio 70

-Xms 3670k

-Xmx 64m

Domyślne wartości parametrów wielkości sterty w systemach 64-bitowych zostały powiększone o około 30%. Ten wzrost ma zrekompensować większy rozmiar obiektów w systemie 64-bitowym.

Przy tych parametrach, jeśli procent wolnej przestrzeni w generacji spadnie poniżej 40%, generacja zostanie rozszerzona w celu utrzymania 40% wolnej przestrzeni, aż do maksymalnego dozwolonego rozmiaru generacji. Podobnie, jeśli wolne miejsce przekroczy 70%, generacja zostanie zakontraktowana, tak że tylko 70% wolnego miejsca będzie wolne, z zastrzeżeniem minimalnej wielkości generacji.

Duże aplikacje serwerowe często doświadczają dwóch problemów z tymi ustawieniami domyślnymi. Jednym z nich jest powolne uruchamianie, ponieważ początkowa sterta jest niewielka i należy zmienić jej rozmiar w wielu dużych kolekcjach. Bardziej palącym problemem jest to, że domyślny maksymalny rozmiar sterty jest nieuzasadniony mały dla większości aplikacji serwerowych. Podstawowe zasady aplikacji serwerowych to:

  • O ile nie masz problemów z przerwami, spróbuj przyznać maszynie wirtualnej jak najwięcej pamięci. Domyślny rozmiar (64 MB) jest często zbyt mały.
  • Ustawienie -Xms i -Xmx na tę samą wartość zwiększa przewidywalność poprzez usunięcie najważniejszej decyzji dotyczącej rozmiaru z maszyny wirtualnej. Jednak maszyna wirtualna nie będzie w stanie zrekompensować, jeśli dokonasz złego wyboru.
  • Zasadniczo, zwiększaj pamięć wraz ze wzrostem liczby procesorów, ponieważ alokacja może być równoległa.

    Jest pełny artykuł

teodor
źródło