Zawsze mogłem przydzielić 1400 megabajtów dla Java SE działającej w 32-bitowym systemie Windows XP (Java 1.4, 1.5 i 1.6).
java -Xmx1400m ...
Dzisiaj wypróbowałem tę samą opcję na nowej maszynie z systemem Windows XP z Javą 1.5_16 i 1.6.0_07 i otrzymałem błąd:
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
Metoda prób i błędów wydaje się, że 1200 megabajtów to najwięcej, jakie mogę przeznaczyć na tym komputerze.
Jakieś pomysły, dlaczego jedna maszyna miałaby pozwolić 1400, a inna tylko 1200?
Edycja: maszyna ma 4 GB pamięci RAM i około 3,5 GB, którą może rozpoznać system Windows.
Odpowiedzi:
Należy pamiętać, że system Windows zarządza pamięcią wirtualną, a maszyna JVM potrzebuje tylko pamięci ciągłej w jej przestrzeni adresowej . Tak więc inne programy działające w systemie nie muszą koniecznie wpływać na rozmiar sterty. Na drodze staną Ci biblioteki DLL, które zostaną załadowane do Twojej przestrzeni adresowej. Niestety optymalizacje w systemie Windows, które minimalizują przenoszenie bibliotek DLL podczas łączenia, zwiększają prawdopodobieństwo, że będziesz mieć pofragmentowaną przestrzeń adresową. Rzeczy, które prawdopodobnie będą przecinać przestrzeń adresową, oprócz zwykłych rzeczy, obejmują oprogramowanie zabezpieczające, oprogramowanie CBT, oprogramowanie szpiegowskie i inne formy złośliwego oprogramowania. Prawdopodobnymi przyczynami rozbieżności są różne poprawki zabezpieczeń, wersje środowiska wykonawczego C itp. Sterowniki urządzeń i inne bity jądra mają swoją własną przestrzeń adresową (pozostałe 2 GB z 4 GB 32-bitowej przestrzeni).
Państwo mogli spróbować przeżywa swoimi powiązaniami DLL w procesie JVM i patrzeć na próby rebase Twój DLL w celu bardziej zwartej przestrzeni adresowej. Nie fajnie, ale jeśli jesteś zdesperowany ...
Alternatywnie możesz po prostu przełączyć się na 64-bitowy system Windows i 64-bitową maszynę JVM. Pomimo tego, co sugerowali inni, podczas gdy spowoduje to większe zużycie pamięci RAM, będziesz mieć znacznie bardziej ciągłą wirtualną przestrzeń adresową, a przydzielanie 2 GB w ciągły sposób byłoby trywialne.
źródło
Ma to związek z ciągłą pamięcią.
Oto kilka informacji, które znalazłem w Internecie dla kogoś, kto wcześniej o to zapytał, prawdopodobnie od „boga maszyn wirtualnych”:
źródło
Ograniczenia rozmiaru sterty Java dla systemu Windows to:
To nie pomaga w uzyskaniu większego stosu Java, ale teraz wiesz, że nie możesz wyjść poza te wartości.
źródło
Oracle JRockit , który może obsłużyć nieciągłą stertę, może mieć rozmiar sterty Java wynoszący 2,85 GB w systemie Windows 2003 / XP z przełącznikiem / 3GB. Wydaje się, że fragmentacja może mieć duży wpływ na wielkość stosu Java.
źródło
JVM potrzebuje ciągłej pamięci iw zależności od tego, co jeszcze działa, co działało wcześniej i jak system Windows zarządzał pamięcią, możesz uzyskać do 1,4 GB ciągłej pamięci. Myślę, że 64-bitowy system Windows pozwoli na większe stosy.
źródło
JVM firmy Sun potrzebuje ciągłej pamięci. Zatem maksymalna ilość dostępnej pamięci jest podyktowana fragmentacją pamięci. Szczególnie biblioteki DLL sterowników mają tendencję do fragmentacji pamięci podczas ładowania do jakiegoś predefiniowanego adresu bazowego. Więc twój sprzęt i jego sterowniki określają, ile pamięci możesz uzyskać.
Dwa źródła z wypowiedziami inżynierów Sun: blog forum
Może inny JVM? Czy próbowałeś Harmony ? Myślę, że planowali zezwolić na pamięć nieciągłą.
źródło
Myślę, że ma to więcej wspólnego z konfiguracją systemu Windows, jak wskazuje ta odpowiedź: Java -Xmx Option
Trochę więcej testów: udało mi się przydzielić 1300 MB na starym komputerze z systemem Windows XP z tylko 768 MB fizycznej pamięci RAM (plus pamięć wirtualna). Na moim komputerze z 2 GB pamięci RAM mogę uzyskać tylko 1220 MB. Na różnych komputerach firmowych (ze starszym Windows XP) udało mi się uzyskać 1400MB. Maszyna z limitem 1220 MB jest całkiem nowa (właśnie zakupiona od firmy Dell), więc może ma nowszy (i bardziej rozdęty) system Windows i DLL (działa na nim Windows XP Pro w wersji 2002 SP2).
źródło
Otrzymałem ten komunikat o błędzie podczas uruchamiania programu java z (ograniczonej pamięci) wirtualnego serwera VPS. Nie podałem żadnych argumentów pamięci i stwierdziłem, że muszę wyraźnie ustawić niewielką wartość, ponieważ wartość domyślna musiała być zbyt wysoka. Np. -Xmx32m (oczywiście musi być dostrojone w zależności od uruchamianego programu).
Po prostu wstawiam to tutaj na wypadek, gdyby ktoś inny otrzymał powyższy komunikat o błędzie bez określania dużej ilości pamięci, tak jak zrobił to pytający.
źródło
JDK / JRE firmy Sun potrzebuje stałej ilości pamięci, jeśli przydzielisz ogromny blok.
System operacyjny i początkowe aplikacje mają tendencję do przydzielania bitów i elementów podczas ładowania, co fragmentuje dostępną pamięć RAM. Jeśli ciągły blok NIE jest dostępny, SUN JDK nie może go użyć. JRockit firmy Bea (nabyty przez Oracle) może przydzielać pamięć z elementów.
źródło
Wydaje się, że wszyscy odpowiadają na temat pamięci ciągłej, ale zaniedbali dostrzeżenie bardziej palącej kwestii.
Nawet przy 100% ciągłej alokacji pamięci nie można mieć sterty o rozmiarze 2 GiB w 32-bitowym systemie operacyjnym Windows (domyślnie *). Dzieje się tak, ponieważ 32-bitowe procesy systemu Windows nie mogą adresować więcej niż 2 GiB miejsca.
Proces Java będzie zawierał perm gen (przed Java 8), rozmiar stosu na wątek, narzut JVM / biblioteki (który znacznie wzrasta z każdą kompilacją), a wszystko to oprócz sterty .
Ponadto flagi maszyny JVM i ich wartości domyślne zmieniają się między wersjami. Po prostu uruchom poniższe, a zobaczysz jakiś pomysł:
Wiele opcji wpływa na podział pamięci w stercie i poza nią. Pozostawiając ci mniej więcej 2 GiB do gry z ...
Ponowne wykorzystanie części tej odpowiedzi kopalni (około Tomcat, ale odnosi się do każdego procesu Java):
źródło
Oto jak zwiększyć rozmiar stronicowania
źródło
** Istnieje wiele sposobów zmiany rozmiaru sterty, np.
Dla mnie zadziałało
Ustaw odpowiednią ścieżkę JAVA_HOME na wypadek, gdybyś zaktualizował Java.
utwórz nową zmienną systemową komputer-> właściwości-> ustawienia zaawansowane- > utwórz nową zmienną systemową
nazwa: _JAVA_OPTION wartość: -Xmx750m
Do Twojej wiadomości: możesz znaleźć domyślną opcję VM w pomocy Intellij - > edytuj niestandardową opcję maszyny wirtualnej , w tym pliku widzisz minimalny i maksymalny rozmiar sterty. **
źródło
Po pierwsze, używanie pliku stronicowania, gdy masz 4 GB pamięci RAM, jest bezużyteczne. System Windows nie może uzyskać dostępu do więcej niż 4 GB (właściwie mniej z powodu dziur w pamięci), więc plik strony nie jest używany.
Po drugie, przestrzeń adresowa jest podzielona na 2, połowę dla jądra, połowę dla trybu użytkownika. Jeśli potrzebujesz więcej pamięci RAM dla swoich aplikacji, użyj opcji / 3 GB w pliku boot.ini (upewnij się, że plik java.exe jest oznaczony jako „duży adres z uwzględnieniem” (więcej informacji w Google).
Po trzecie, myślę, że nie można przydzielić pełnych 2 GB przestrzeni adresowej, ponieważ java marnuje część pamięci wewnętrznie (na wątki, kompilator JIT, inicjalizację maszyny wirtualnej itp.). Użyj przełącznika / 3GB, aby uzyskać więcej.
źródło