Jak radzić sobie z " java.lang.OutOfMemoryError: błąd Java heap space" (rozmiar stosu 64 MB)

Piszę aplikację po stronie klienta Swing (graficzny projektant czcionek) na Java 5. Ostatnio napotkałem błąd java.lang.OutOfMemoryError: Java heap space, ponieważ nie jestem zachowawczy w zakresie użycia pamięci. Użytkownik może otworzyć nieograniczoną liczbę plików, a program utrzymuje otwarte obiekty w pamięci. Po krótkim badaniu znalazłem ergonomię w wirtualnej maszynie Javy 5.0 i innych mówiących na maszynie z systemem Windows, że JVM domyślnie ustawia maksymalny rozmiar sterty jako 64MB.

Biorąc pod uwagę to sytuacja, Jak mam poradzić sobie z tym ograniczeniem?

Mógłbym Zwiększyć maksymalny rozmiar sterty używając opcji linii poleceń do Javy, ale wymagałoby to znalezienia dostępnej pamięci RAM i napisania jakiegoś uruchamiającego programu lub skryptu. Poza tym, zwiększenie do pewnego skończonego max Nie ostatecznie pozbyć się problemu.

Mógłbym przepisać część mojego kodu do persist objects do systemu plików często(korzystanie z bazy danych to to samo), aby zwolnić pamięć. Może się udać, ale to pewnie też dużo pracy.

Jeśli mógłbyś wskazać mi szczegóły powyższych pomysłów lub jakieś alternatywy, takie jak automatyczna pamięć wirtualna, rozszerzająca rozmiar sterty dynamicznie , to będzie świetnie.

Author: Bhaskara Arani, 2008-09-01

18 answers

Ostatecznie zawsze masz skończone maksimum sterty, aby użyć bez względu na to, na jakiej platformie jesteś uruchomiony. W Windows 32 bit jest to około 2GB(nie konkretnie sterty, ale całkowita ilość pamięci na proces). Po prostu zdarza się, że Java decyduje się na zmniejszenie domyślnej wartości (prawdopodobnie tak, że programista nie może tworzyć programów, które mają uciekającą alokację pamięci bez napotkania tego problemu i konieczności dokładnego zbadania, co robi).

Tak więc biorąc pod uwagę, że istnieje kilka podejścia, które możesz podjąć, aby określić, jakiej ilości pamięci potrzebujesz lub zmniejszyć ilość pamięci, której używasz. Częstym błędem w przypadku języków pobranych ze śmieci, takich jak Java lub C#, jest trzymanie odniesień do obiektów, których już nie używasz, lub przydzielanie wielu obiektów, gdy można ich ponownie użyć. Tak długo, jak obiekty mają odniesienie do nich, będą nadal używać przestrzeni sterty, ponieważ garbage collector nie usunie ich.

W tym przypadku możesz użyć Java memory profiler, aby określić, jakie metody w programie przydzielają dużą liczbę obiektów, a następnie określić, czy istnieje sposób, aby upewnić się, że nie są już odwoływane, lub nie przydzielać ich w pierwszej kolejności. Jedną z opcji, której używałem w przeszłości, jest " JMP " http://www.khelekore.org/jmp/.

Jeśli stwierdzisz, że przydzielasz te obiekty z jakiegoś powodu i musisz trzymać się odniesień (w zależności od tego, co robisz, może to mieć miejsce), wystarczy zwiększyć maksymalny rozmiar sterty po uruchomieniu programu. Jednak po wykonaniu profilowania pamięci i zrozumieniu, w jaki sposób przydzielane są obiekty, powinieneś mieć lepszy pomysł na to, ile pamięci potrzebujesz.

Ogólnie rzecz biorąc, jeśli nie możesz zagwarantować, że twój program będzie działał w określonej ilości pamięci (być może w zależności od wielkości wejścia), zawsze napotkasz ten problem. Dopiero po wyczerpaniu tego wszystkiego będziesz musiał zajrzeć do buforowania obiektów na dysk itd. W tym momencie powinieneś mieć bardzo dobry powód, aby powiedzieć "potrzebuję Xgb pamięci" do czegoś i nie możesz obejść tego, ulepszając swoje algorytmy lub wzorce alokacji pamięci. Zwykle dotyczy to algorytmów operujących na dużych zbiorach danych (takich jak Baza Danych lub jakiś program do analizy naukowej), a wtedy przydatne stają się techniki takie jak buforowanie i mapowanie pamięci IO.

 196
Author: Ben Childs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-02 21:52:52

Uruchom Javę z opcją wiersza poleceń -Xmx, która ustawia maksymalny rozmiar sterty.

Szczegóły znajdziesz tutaj..

 101
Author: Dave Webb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-11 08:42:08

Możesz określić dla każdego projektu, ile miejsca na stercie potrzebuje twój projekt

Poniżej znajduje się zaćmienie Heliosa / Juno / Keplera:

Prawy przycisk myszy na

 Run As - Run Configuration - Arguments - Vm Arguments, 

Następnie dodaj to

-Xmx2048m
 77
Author: allenhwkim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-08 08:02:54

Zwiększenie rozmiaru stosu nie jest "naprawą", jest "tynkiem", w 100% tymczasowym. Znowu rozbije się gdzieś indziej. Aby uniknąć tych problemów, napisz Kod o wysokiej wydajności.

  1. używaj zmiennych lokalnych tam, gdzie to możliwe.
  2. Upewnij się, że wybrałeś właściwy obiekt (np. wybór pomiędzy String, StringBuffer i StringBuilder)
  3. Użyj dobrego systemu kodu dla swojego programu (np. używając zmiennych statycznych VS zmiennych niestatycznych)
  4. inne rzeczy, które mogą działać na Twoim kod.
  5. spróbuj poruszać się z multy THREADING
 30
Author: Yohan Weerasinghe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-02 21:58:26

Wielkie zastrzeżenie - - - - w moim biurze stwierdziliśmy, że (na niektórych maszynach z windows) nie możemy przeznaczyć więcej niż 512m dla Java heap. Okazało się, że jest to spowodowane zainstalowanym na niektórych z tych komputerów produktem Kaspersky anti-virus. Po odinstalowaniu tego produktu AV okazało się, że możemy przeznaczyć co najmniej 1.6 gb, czyli-Xmx1600m (M jest obowiązkowe inne mądre doprowadzi to do kolejnego błędu "zbyt mała początkowa kupa") działa.

Nie mam pojęcia, czy tak się dzieje z innymi produktami AV, ale prawdopodobnie dzieje się tak, ponieważ program AV rezerwuje mały blok pamięci w każdej przestrzeni adresowej, zapobiegając tym samym jednemu naprawdę dużemu przydziale.

 28
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-06 13:35:43

Argument VM zadziałał dla mnie w eclipse. Jeśli używasz eclipse w wersji 3.4, wykonaj następujące czynności

Przejdź do Run --> Run Configurations --> następnie wybierz projekt pod Maven build -- > następnie wybierz zakładkę " JRE " -- > następnie wprowadź -Xmx1024m.

Alternatywnie możesz zrobić Run --> Run Configurations --> select the "JRE" tab --> następnie wpisać - Xmx1024m

Powinno to zwiększyć ilość pamięci dla wszystkich buildów/projektów. Powyższy rozmiar pamięci to 1 GB. Możesz zoptymalizować sposób, w jaki chcesz.

 18
Author: loveall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-12 14:50:54

Tak, za pomocą-Xmx możesz skonfigurować dla siebie więcej pamięci JVM. Aby mieć pewność, że nie wyciekasz ani nie marnujesz pamięci. Zrób zrzut sterty i użyj analizatora pamięci Eclipse do analizy zużycia pamięci.

 15
Author: kohlerm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-09 08:22:25

Chciałbym dodać rekomendacje z oracle trouble shooting Artykuł

Wyjątek w wątku thread_name: java.lang.OutOfMemoryError: Java heap space

Komunikat szczegółowy Java heap space wskazuje, że obiekt nie może zostać przydzielony do Java heap. Ten błąd nie musi oznaczać wycieku pamięci

możliwe przyczyny:

  1. prosty problem z konfiguracją , gdzie określony rozmiar sterty jest niewystarczająca do zastosowania.

  2. Aplikacja nieumyślnie przechowuje odwołania do obiektów , co zapobiega ich zbieraniu.

  3. nadmierne stosowanie finalizatorów .

Inne potencjalne źródło tego błędu pojawia się w aplikacjach, które nadmiernie wykorzystują finalizery. Jeśli klasa ma metodę finalize, to obiekty tego typu nie mają odzyskiwanej przestrzeni na śmieci czas zbierania

Po garbage collection obiekty są w kolejce do finalizacji , co następuje w późniejszym czasie. finalizery są uruchamiane przez wątek demona obsługujący kolejkę finalizacji. Jeśli wątek finalizer nie nadąża za kolejką finalizacji, to sterta Javy może się wypełnić i ten typ wyjątku OutOfMemoryError zostanie wyrzucony.

Jednym ze scenariuszy, który może spowodować taką sytuację jest aplikacja tworzy wątki o wysokim priorytecie, które powodują wzrost kolejki finalizacji w tempie szybszym niż tempo, z jakim wątek finalizatora obsługuje tę kolejkę.

 8
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-29 15:35:27

Wykonaj poniższe kroki:

  1. Open catalina.sh z tomcat / bin.

  2. Chnage JAVA_OPTS to

    JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1536m 
    -Xmx1536m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m 
    -XX:MaxPermSize=256m -XX:+DisableExplicitGC"
    
  3. Uruchom ponownie tomcat

 7
Author: Pradip Bhatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-03 17:59:03

Czytałem gdzie indziej, że można spróbować-złapać Javę.lang.OutOfMemoryError i na bloku catch, możesz uwolnić wszystkie zasoby, które wiesz, że mogą używać dużo pamięci, bliskie połączenia i tak dalej, a następnie zrobić System.gc () następnie spróbuj ponownie cokolwiek zamierzałeś zrobić.

Inny sposób jest taki, chociaż Nie wiem, czy to zadziała, ale obecnie testuję, czy zadziała na mojej aplikacji.

Chodzi o to, aby usuwać śmieci przez wywołanie systemu.gc (), który jest znany z zwiększania wolnej pamięci. Możesz to sprawdzać po wykonaniu kodu pożerającego pamięć.

//Mimimum acceptable free memory you think your app needs
long minRunningMemory = (1024*1024);

Runtime runtime = Runtime.getRuntime();

if(runtime.freeMemory()<minRunningMemory)
 System.gc();
 6
Author: mwangi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-17 08:19:44

Miałem do czynienia z tym samym problemem java heap size. Mam dwa rozwiązania jeśli używasz java 5 (1.5).

1st: - po prostu zainstaluj jdk1. 6 i przejdź do preferencji eclipse i ustaw ścieżkę jre jav1 1.6 tak jak zainstalowałeś.

2nd: - Sprawdź argument VM i niech będzie cokolwiek to jest. wystarczy dodać jeden wiersz poniżej wszystkich argumentów obecnych w argumentach VM jako -Xms512m-Xmx512m-XX: MaxPermSize=...m (192m).

Myślę, że zadziała...

 6
Author: Soumya Sandeep Mohanty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-10 18:48:49

Łatwym sposobem rozwiązania OutOfMemoryError w Javie jest zwiększenie maksymalnego rozmiaru sterty za pomocą opcji JVM -Xmx512M, to natychmiast rozwiąże Twój OutOfMemoryError. Jest to moje preferowane rozwiązanie, gdy wydostaję się OutOfMemoryError w Eclipse, Maven lub ANT podczas budowania projektu, ponieważ na podstawie rozmiaru projektu można łatwo zabrakło pamięci.

Oto przykład zwiększenia maksymalnego rozmiaru sterty JVM, również lepiej zachować-Xmx do-Xms rację 1: 1 lub 1: 1.5 jeśli ustawiasz rozmiar sterty w Twoja aplikacja java.

export JVM_ARGS="-Xms1024m -Xmx1024m"

Link Referencyjny

 6
Author: chaukssey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-20 10:34:39

Jeśli chcesz monitorować zużycie pamięci w czasie wykonywania, java.lang.pakiet zarządzania oferuje Mbeany, które mogą być używane do monitorowania pul pamięci w maszynie wirtualnej (np. eden space, tenured generation itp.), a także zachowanie usuwania śmieci.

Wolna przestrzeń sterty zgłaszana przez te Mbeany będzie się znacznie różnić w zależności od zachowania GC, szczególnie jeśli aplikacja generuje wiele obiektów, które są później GC-ed. Jednym z możliwych sposobów jest monitorowanie wolnej przestrzeni sterty po każdym full-GC, którego możesz użyć do podjęcia decyzji o zwolnieniu pamięci przez utrzymywanie obiektów.

Ostatecznie najlepszym rozwiązaniem jest ograniczenie retencji pamięci tak dalece, jak to możliwe, podczas gdy wydajność pozostaje akceptowalna. Jak wspomniano w poprzednim komentarzu, pamięć jest zawsze ograniczona, ale Twoja aplikacja powinna mieć strategię radzenia sobie z wyczerpaniem pamięci.

 5
Author: Leigh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-09 12:04:30

Zauważ, że jeśli potrzebujesz tego w sytuacji wdrożenia, rozważ użycie Java WebStart (z wersją "ondisk", a nie sieciową - możliwe w Javie 6u10 i nowszych), ponieważ pozwala na podanie różnych argumentów do JVM w sposób wieloplatformowy.

W przeciwnym razie będziesz potrzebował programu uruchamiającego specyficznego dla systemu operacyjnego, który ustawia potrzebne argumenty.

 3
Author: Thorbjørn Ravn Andersen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-19 04:45:22

Domyślnie dla rozwoju JVM używa małych rozmiarów i małych konfiguracji dla innych funkcji związanych z wydajnością. Ale do produkcji można dostrajać np. (dodatkowo może istnieć konfiguracja serwera aplikacji) - > (Jeśli nadal nie ma wystarczającej ilości pamięci, aby spełnić żądanie, A sterta osiągnęła już maksymalny rozmiar, wystąpi OutOfMemoryError)

-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        set java thread stack size

-XX:ParallelGCThreads=8
-XX:+CMSClassUnloadingEnabled
-XX:InitiatingHeapOccupancyPercent=70
-XX:+UnlockDiagnosticVMOptions
-XX:+UseConcMarkSweepGC
-Xms512m
-Xmx8192m
-XX:MaxPermSize=256m (in java 8 optional)

Na przykład: na platformie linux dla trybu produkcyjnego preferowane ustawienia.

Po pobraniu i skonfigurowaniu serwer z tą drogą http://www.ehowstuff.com/how-to-install-and-setup-apache-tomcat-8-on-centos-7-1-rhel-7/

1.Utwórz setenv.sh plik w folderze / opt / tomcat / bin /

   touch /opt/tomcat/bin/setenv.sh

2.Otwórz i napisz ten params dla ustawienia preferowanego trybu.

nano  /opt/tomcat/bin/setenv.sh 

export CATALINA_OPTS="$CATALINA_OPTS -XX:ParallelGCThreads=8"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+CMSClassUnloadingEnabled"
export CATALINA_OPTS="$CATALINA_OPTS -XX:InitiatingHeapOccupancyPercent=70"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UnlockDiagnosticVMOptions"
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseConcMarkSweepGC"
export CATALINA_OPTS="$CATALINA_OPTS -Xms512m"
export CATALINA_OPTS="$CATALINA_OPTS -Xmx8192m"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxMetaspaceSize=256M"

3.service tomcat restart

Zauważ, że JVM używa więcej pamięci niż tylko sterty. Na przykład Metody Java, stosy wątków i natywne uchwyty są przydzielane w pamięci oddzielony od sterty, a także JVM wewnętrzny struktury danych.

 3
Author: Musa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-03 12:32:02

Jeśli nadal przydzielasz i przechowujesz odwołania do obiektu, zapełnisz dowolną ilość pamięci, jaką posiadasz.

Jedną z opcji jest zamknięcie i otwarcie przezroczystego pliku podczas przełączania kart (zachowujesz tylko wskaźnik do pliku, a gdy użytkownik przełącza kartę, zamykasz i czyścisz wszystkie obiekty... to spowolni zmianę Pliku... ale...), a może zachować tylko 3 lub 4 pliki w pamięci.

Inną rzeczą, którą powinieneś zrobić, jest to, że gdy użytkownik otworzy plik, załaduj go i przechwyć dowolny OutOfMemoryError, następnie (ponieważ nie można otworzyć pliku) zamknąć ten plik, wyczyścić jego obiekty i ostrzec użytkownika, że powinien zamknąć nieużywane pliki.

Twój pomysł dynamicznego rozszerzania pamięci wirtualnej nie rozwiązuje problemu, ponieważ maszyna ma ograniczone zasoby, więc powinieneś zachować ostrożność i rozwiązywać problemy z pamięcią (lub przynajmniej być ostrożnym z nimi).

Kilka wskazówek, które widziałem z wyciekami pamięci to:

--> pamiętaj, że jeśli umieścisz coś w zbiorze a potem zapomnij o tym, nadal masz do niego silne odniesienie, Więc anuluj kolekcję, wyczyść ją lub zrób coś z nią... jeśli nie, trudno będzie znaleźć wyciek pamięci.

-- > może, używając kolekcji ze słabymi referencjami (weakhashmap...) może pomóc w problemach z pamięcią, ale ty musisz być ostrożnym z tym, ponieważ może się okazać, że szukany obiekt został zebrany.

-- > innym pomysłem jaki znalazłem jest stworzenie trwałego zbioru, który przechowywane w obiektach bazy danych. To byłoby chyba najlepsze podejście...

 0
Author: SoulWanderer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-29 07:47:13

Jeśli chodzi o netbeans, możesz ustawić maksymalny rozmiar sterty, aby rozwiązać problem. Najpierw przejdź do "Uruchom", a następnie -- > "Ustaw konfigurację projektu" -- > "Dostosuj" -- > "Uruchom" wyskakującego okna -- > "Opcja maszyny wirtualnej" -- > wypełnij "- Xms2048m-Xmx2048m".

 0
Author: Xiaogang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-12 22:56:06

Jeśli ten problem występuje w Wildfly 8 i JDK1. 8, to musimy określić ustawienia MaxMetaSpace zamiast ustawień PermGen.

Na przykład musimy dodać poniżej konfigurację w setenv.sh akta wildfly. JAVA_OPTS="$JAVA_OPTS -XX:MaxMetaspaceSize=256M"

Aby uzyskać więcej informacji, sprawdź Wildfly Heap Issue

 0
Author: satish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-28 05:10:30