Pytanie nie dotyczy maksymalnego rozmiaru sterty w 32-bitowym systemie operacyjnym, biorąc pod uwagę, że 32-bitowe systemy operacyjne mają maksymalny rozmiar adresowalnej pamięci wynoszący 4 GB, a maksymalny rozmiar sterty maszyny JVM zależy od tego, ile ciągłej wolnej pamięci można zarezerwować.
Bardziej interesuje mnie znajomość maksymalnego (zarówno teoretycznego, jak i praktycznie osiągalnego) rozmiaru sterty dla 32-bitowej maszyny JVM działającej w 64-bitowym systemie operacyjnym. Zasadniczo szukam odpowiedzi podobnych do liczb w powiązanym pytaniu dotyczącym SO .
Jeśli chodzi o to, dlaczego używana jest 32-bitowa JVM zamiast 64-bitowej, przyczyna nie jest techniczna, ale raczej administracyjna / biurokratyczna - prawdopodobnie jest za późno na zainstalowanie 64-bitowej maszyny JVM w środowisku produkcyjnym.
Możesz zapytać Java Runtime:
Spowoduje to zgłoszenie „Max Memory” w oparciu o domyślną alokację sterty. Więc nadal musisz grać z
-Xmx
(na HotSpot ). Zauważyłem, że działając w 64-bitowym systemie Windows 7 Enterprise, moja 32-bitowa maszyna JVM HotSpot może przydzielić do 1577 MiB:Podczas gdy w przypadku 64-bitowej maszyny JVM w tym samym systemie operacyjnym jest oczywiście znacznie wyższy (około 3 TiB)
Jak już wspominali inni, zależy to od systemu operacyjnego.
W przypadku 64-bitowego systemu operacyjnego hosta, jeśli JVM jest 32-bitowa, nadal będzie zależeć, najprawdopodobniej jak powyżej, jak pokazano.
- UPDATE 20110905 : Chciałem tylko wskazać kilka innych obserwacji / szczegółów:
Runtime.MaxMemory
jaką można przydzielić, zależy również od zestawu roboczego systemu operacyjnego . Kiedyś uruchomiłem to, gdy miałem również uruchomiony VirtualBox i stwierdziłem, że nie mogę pomyślnie uruchomić maszyny wirtualnej HotSpot JVM-Xmx1590M
i musiałem zmniejszyć jej rozmiar. Oznacza to również, że możesz uzyskać więcej niż 1590 M, w zależności od rozmiaru zestawu roboczego w danym momencie (chociaż nadal utrzymuję, że będzie poniżej 2 GB dla 32-bitów ze względu na projekt systemu Windows)źródło
Nie określasz, który system operacyjny.
W systemie Windows (dla mojej aplikacji - długo działającej aplikacji do zarządzania ryzykiem) zauważyliśmy, że nie możemy przejść dalej niż 1280 MB na 32-bitowym systemie Windows. Wątpię, czy uruchomienie 32-bitowej maszyny JVM pod 64-bitową miało jakiekolwiek znaczenie.
Przenieśliśmy aplikację na Linuksa i używamy 32-bitowej maszyny JVM na 64-bitowym sprzęcie i mamy maszynę wirtualną 2,2 GB działającą dość łatwo.
Największym problemem, jaki możesz mieć, jest GC w zależności od tego, do czego używasz pamięci.
źródło
Od 4.1.2 Rozmiar sterty :
Znalazłem tutaj całkiem dobrą odpowiedź: maksymalna pamięć Java w systemie Windows XP .
źródło
Niedawno mieliśmy z tym pewne doświadczenia. Niedawno przeportowaliśmy system z Solaris (x86-64 wersja 5.10) na Linux (RedHat x86-64) i zdaliśmy sobie sprawę, że mamy mniej dostępnej pamięci dla 32-bitowego procesu JVM w systemie Linux niż Solaris.
W przypadku Solaris to prawie 4 GB (http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit).
Uruchomiliśmy naszą aplikację z -Xms2560m -Xmx2560m -XX: MaxPermSize = 512m -XX: PermSize = 512m bez żadnych problemów w systemie Solaris przez ostatnie kilka lat. Próbowałem przenieść go na Linuksa i mieliśmy problemy z losowymi błędami braku pamięci podczas uruchamiania. Mogliśmy tylko sprawić, by konsekwentnie uruchamiał się na -Xms2300 -Xmx2300 . Następnie poinformowano nas o tym przez wsparcie.
źródło
Ograniczenia 32-bitowej maszyny JVM w 64-bitowym systemie operacyjnym będą dokładnie takie same, jak ograniczenia 32-bitowej maszyny JVM w 32-bitowym systemie operacyjnym. W końcu 32-bitowa JVM będzie działać na 32-bitowej maszynie wirtualnej (w sensie wirtualizacji), więc nie będzie wiedzieć, że działa na 64-bitowym systemie operacyjnym / maszynie.
Jedyną zaletą uruchamiania 32-bitowej maszyny JVM w 64-bitowym systemie operacyjnym w porównaniu z 32-bitowym systemem operacyjnym jest to, że można mieć więcej pamięci fizycznej i dlatego rzadziej napotyka wymianę / stronicowanie. Ta zaleta jest jednak w pełni widoczna tylko wtedy, gdy masz wiele procesów.
źródło
Kiedy pracowałem dla BEA, stwierdziliśmy, że przeciętna aplikacja faktycznie działała wolniej w 64-bitowej JVM, niż działała na 32-bitowej JVM. W niektórych przypadkach wydajność była nawet o 25% wolniejsza. Tak więc, chyba że Twoja aplikacja naprawdę potrzebuje całej tej dodatkowej pamięci, lepiej byłoby skonfigurować więcej serwerów 32-bitowych.
Jak sobie przypominam, trzy najczęstsze techniczne uzasadnienia korzystania z 64-bitowej wersji, z którymi zetknął się personel serwisowy BEA to:
.
źródło
JROCKIT JVM aktualnie należąca do Oracle obsługuje nieciągłe użycie sterty, dzięki czemu 32-bitowa maszyna JVM może uzyskać dostęp do ponad 3,8 GB pamięci, gdy maszyna JVM działa w 64-bitowym systemie operacyjnym Windows. (2,8 GB w przypadku 32-bitowego systemu operacyjnego).
http://blogs.oracle.com/jrockit/entry/how_to_get_almost_3_gb_heap_on_windows
JVM można bezpłatnie pobrać (wymagana rejestracja) pod adresem
http://www.oracle.com/technetwork/middleware/jrockit/downloads/index.html
źródło
Oto kilka testów pod Solaris i Linux 64-bit
Solaris 10 - SPARC - maszyna T5220 z 32 GB RAM (i około 9 GB wolnego)
BTW: Najwyraźniej Java nie przydziela dużo pamięci podczas uruchamiania. Wydawało się, że zajęło to tylko około 100 MB na uruchomioną instancję (zacząłem 10)
Solaris 10 - x86 - VMWare VM z 8 GB RAM (około 3 GB wolnego *)
3 GB wolnej pamięci RAM nie jest prawdą. Jest duży fragment pamięci RAM, którego używają pamięci podręczne ZFS, ale nie mam uprawnień administratora, aby sprawdzić, ile dokładnie
RedHat 5.5 - x86 - VMWare VM z 4 GB RAM (używane około 3,8 GB - 200 MB w buforach i 3,1 GB w pamięci podręcznej, czyli około 3 GB wolnego)
Ta sama maszyna korzystająca z JRE 7
źródło
Powinno być dużo lepiej
W przypadku 32-bitowej maszyny JVM działającej na 64-bitowym hoście wyobrażam sobie, że to, co pozostanie na stercie, będzie dowolną niefragmentowaną przestrzenią wirtualną dostępną po JVM, jej własną biblioteką DLL i załadowaniem wszelkich elementów kompatybilności z 32-bitowym systemem operacyjnym. Wydaje mi się, że 3 GB powinno być możliwe, ale o ile lepiej to zależy od tego, jak dobrze sobie radzisz w 32-bitowym host-land.
Ponadto, nawet jeśli mógłbyś stworzyć gigantyczną stertę 3 GB, możesz nie chcieć, ponieważ spowoduje to, że przerwy w GC staną się potencjalnie kłopotliwe. Niektórzy ludzie po prostu uruchamiają więcej maszyn JVM, aby użyć dodatkowej pamięci zamiast jednej gigantycznej. Wyobrażam sobie, że właśnie teraz dostrajają maszyny JVM, aby działały lepiej z gigantycznymi stertami.
Trochę trudno jest dokładnie wiedzieć, o ile lepiej możesz zrobić. Domyślam się, że twoją 32-bitową sytuację można łatwo określić eksperymentalnie. Z pewnością trudno to przewidzieć abstrakcyjnie, ponieważ wiele rzeczy ma na to wpływ, szczególnie dlatego, że przestrzeń wirtualna dostępna na 32-bitowych hostach jest raczej ograniczona. Sterta musi istnieć w ciągłej pamięci wirtualnej, więc fragmentacja przestrzeni adresowej dla dll i wewnętrzne użycie przestrzeni adresowej przez jądro systemu operacyjnego określi zakres możliwych alokacji.
System operacyjny będzie wykorzystywał część przestrzeni adresowej do mapowania urządzeń sprzętowych i własnych dynamicznych alokacji. Chociaż ta pamięć nie jest mapowana na przestrzeń adresową procesu java, jądro systemu operacyjnego nie może jednocześnie uzyskać do niej dostępu i Twojej przestrzeni adresowej, więc ograniczy rozmiar przestrzeni wirtualnej dowolnego programu.
Ładowanie DLL zależy od implementacji i wydania maszyny JVM. Ładowanie jądra systemu operacyjnego zależy od ogromnej liczby rzeczy, wersji, sprzętu, liczby zmapowanych rzeczy do tej pory od ostatniego restartu, kto wie ...
W podsumowaniu
Założę się, że dostaniesz 1-2 GB w 32-bitowej ziemi i około 3 w 64-bitowej, więc ogólna poprawa wynosi około 2x .
źródło
W Solarisie limit ten wynosił około 3,5 GB od wersji Solaris 2.5. (około 10 lat temu)
źródło
Miałem te same problemy z maszyną JVM, z której korzysta App Inventor dla Android Blocks Editor. Ustawia pryzmę na maks. 925 m. To za mało, ale nie mogłem ustawić więcej niż około 1200m, w zależności od różnych czynników losowych na mojej maszynie.
Pobrałem Nightly, 64-bitową przeglądarkę beta z Firefoksa, a także 64-bitową wersję JAVA 7.
Nie znalazłem jeszcze mojego nowego limitu sterty, ale właśnie otworzyłem maszynę JVM o wielkości sterty 5900m . Nie ma problemu!
Używam Win 7 64 bit Ultimate na komputerze z 24 GB pamięci RAM.
źródło
Próbowałem ustawić rozmiar sterty do 2200M na 32-bitowej maszynie Linux i JVM działało dobrze. JVM nie uruchomił się, kiedy ustawiłem go na 2300M.
źródło
To jest ciężkie strojenie, ale możesz zdobyć stertę 3 GB.
http://www.microsofttranslator.com/bv.aspx?from=&to=en&a=http://forall.ru-board.com/egor23/online/FAQ/Virtual_Memory/Limits_Virtual_Memory.html
źródło
jeszcze jeden punkt dla 32-bitowej JVM hotspot: - natywna pojemność sterty = 4 Gig - Java Heap - PermGen;
Może to być szczególnie trudne w przypadku 32-bitowej maszyny JVM, ponieważ Java Heap i natywny Heap są w wyścigu. Im większa sterta Java, tym mniejsza sterta natywna. Próba skonfigurowania dużej sterty dla 32-bitowej maszyny wirtualnej, np. 2,5 GB +, zwiększa ryzyko natywnego OutOfMemoryError w zależności od rozmiaru aplikacji, liczby wątków itp.
źródło
Ograniczenie wynika również z faktu, że w przypadku
32 bit
maszyny wirtualnejheap
sama musi zaczynać się od adresu zero, jeśli chcesz to wszystko4GB
.Pomyśl o tym, jeśli chcesz się do czegoś odwołać poprzez:
tj .: odniesienie, które ma tę konkretną reprezentację bitów, oznacza to, że próbujesz uzyskać dostęp do pierwszej pamięci ze sterty. Aby było to możliwe, sterta musi zaczynać się od adresu zero. Ale to się nigdy nie zdarza, zaczyna się z pewnym przesunięciem od zera:
Ponieważ sterta nigdy nie zaczyna się od adresu zerowego w an
OS
, jest sporo bitów, które nigdy nie są używane z32
odniesienia do bitów, a zatem sterta, do której można się odwołać, jest mniejsza.źródło
Teoretycznie 4 GB, ale w praktyce (dla IBM JVM):
Win 2k8 64, IBM Websphere Application Server 8.5.5 32bit
C:\IBM\WebSphere\AppServer\bin>managesdk.bat -listAvailable -verbose CWSDK1003I: Доступные SDK: CWSDK1005I: Имя SDK: 1.6_32 - com.ibm.websphere.sdk.version.1.6_32=1.6 - com.ibm.websphere.sdk.bits.1.6_32=32 - com.ibm.websphere.sdk.location.1.6_32=${WAS_INSTALL_ROOT}/java - com.ibm.websphere.sdk.platform.1.6_32=windows - com.ibm.websphere.sdk.architecture.1.6_32=x86_32 - com.ibm.websphere.sdk.nativeLibPath.1.6_32=${WAS_INSTALL_ROOT}/lib/native/win /x86_32/ CWSDK1001I: Задача managesdk выполнена успешно. C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2036 MaxMemory JVMJ9GC017E -Xmx слишком мала, должна быть не меньше 1 M байт JVMJ9VM015W Ошибка инициализации для библиотеки j9gc26(2): Не удалось инициализи ровать Could not create the Java virtual machine. C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2047M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 2146435072 (2047.0 MiB) Free Memory: 3064536 (2.9225692749023438 MiB) C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2048M MaxMemory JVMJ9VM015W Ошибка инициализации для библиотеки j9gc26(2): Не удалось создать эк земпляр кучи; запрошено 2G Could not create the Java virtual machine.
RHEL 6.4 64, IBM Websphere Application Server 8.5.5 32-bitowy
[bin]./java -Xmx3791M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 3975151616 (3791.0 MiB) Free Memory: 3232992 (3.083221435546875 MiB) [root@nagios1p bin]# ./java -Xmx3793M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 3977248768 (3793.0 MiB) Free Memory: 3232992 (3.083221435546875 MiB) [bin]# /opt/IBM/WebSphere/AppServer/bin/managesdk.sh -listAvailable -verbose CWSDK1003I: Available SDKs : CWSDK1005I: SDK name: 1.6_32 - com.ibm.websphere.sdk.version.1.6_32=1.6 - com.ibm.websphere.sdk.bits.1.6_32=32 - com.ibm.websphere.sdk.location.1.6_32=${WAS_INSTALL_ROOT}/java - com.ibm.websphere.sdk.platform.1.6_32=linux - com.ibm.websphere.sdk.architecture.1.6_32=x86_32 -com.ibm.websphere.sdk.nativeLibPath.1.6_32=${WAS_INSTALL_ROOT}/lib/native/linux/x86_32/ CWSDK1001I: Successfully performed the requested managesdk task.
źródło