Jak poradzić sobie z "java.lang.OutOfMemoryError: Miejsce na stercie w Javie" błąd?

Piszę aplikację po stronie klienta Swing (graficzny projektant czcionek) na Java 5. Ostatnio napotykam na java.lang.OutOfMemoryError: Java heap space error, ponieważ nie jestem konserwatywny w kwestii wykorzystania pamięci. Użytkownik może otworzyć nieograniczoną liczbę plików, a program przechowuje otwarte obiekty w pamięci. Po szybkich poszukiwaniach znalazłem Ergonomia w 5.0 Java Virtual Machine i innych mówiących, że na maszynie Windows JVM domyślnie ustawia maksymalny rozmiar sterty jako 64MB.

Biorąc pod uwagę tę sytuację, jak powinienem sobie poradzić z tym ograniczeniem?

Mógłbym zwiększyć max heap size używając opcji command line w java, ale to wymagałoby sprawdzenia dostępnej pamięci RAM i napisania jakiegoś programu lub skryptu uruchamiającego. Poza tym, zwiększenie do jakiegoś nieskończonego maksimum nie ostatecznie pozbywa się problemu.

Mógłbym przepisać część mojego kodu tak, żeby często zapisywał obiekty do systemu plików (używanie bazy danych to to samo), żeby zwolnić pamięć. To może zadziałać, ale to też pewnie dużo pracy.

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

Rozwiązanie

Ostatecznie zawsze masz skończoną maksymalną ilość sterty do wykorzystania bez względu na platformę, na której pracujesz. W Windows 32 bit jest to około 2GB (nie konkretnie sterty, ale całkowita ilość pamięci na proces). Tak się składa, że Java decyduje się uczynić domyślnie mniejszą (przypuszczalnie po to, aby programista nie mógł tworzyć programów, które mają ucieczkę alokacji pamięci bez napotkania tego problemu i konieczności zbadania dokładnie, co robią).

Tak więc istnieje kilka podejść, które możesz zastosować, aby określić, jaka ilość pamięci jest potrzebna lub aby zmniejszyć ilość pamięci, której używasz. Jednym z powszechnych błędów w językach typu Java czy C# jest utrzymywanie odniesień do obiektów, których już nie używasz, lub alokowanie wielu obiektów, gdy mógłbyś je wykorzystać zamiast tego. Tak długo jak obiekty posiadają referencję do nich, będą one nadal korzystać z przestrzeni sterty, ponieważ garbage collector ich nie usunie.

W tym przypadku możesz użyć profilera pamięci Java, aby określić, które metody w twoim programie alokują dużą liczbę obiektów, a następnie określić, czy istnieje sposób, aby upewnić się, że nie ma już do nich odniesień, lub aby nie alokować ich w ogóle. Jedną z opcji, której używałem w przeszłości, jest "JMP" .

Jeśli stwierdzisz, że alokujesz te obiekty z jakiegoś powodu i musisz zachować referencje (w zależności od tego, co robisz, może to być przypadek), będziesz musiał po prostu zwiększyć maksymalny rozmiar sterty podczas uruchamiania programu. Jednakże, gdy wykonasz profilowanie pamięci i zrozumiesz, w jaki sposób twoje obiekty są alokowane, powinieneś mieć lepsze pojęcie o tym, ile pamięci potrzebujesz.

Ogólnie rzecz biorąc, jeśli nie możesz zagwarantować, że twój program będzie działał w skończonej ilości pamięci (być może w zależności od wielkości danych wejściowych), zawsze napotkasz ten problem. Dopiero po wyczerpaniu tego wszystkiego będziesz musiał spojrzeć na buforowanie obiektów na dysku itp. W tym momencie powinieneś mieć bardzo dobry powód, aby powiedzieć "Potrzebuję Xgb pamięci" dla czegoś i nie możesz'obejść tego poprzez poprawę swoich algorytmów lub wzorców alokacji pamięci. Ogólnie rzecz biorąc, będzie to miało miejsce tylko w przypadku algorytmów działających na dużych zbiorach danych (takich jak baza danych lub jakiś program do analizy naukowej), a następnie techniki takie jak buforowanie i mapowanie pamięci IO stają się przydatne.

Komentarze (1)

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

Zobacz tutaj po szczegóły.

Komentarze (3)

Tak, z -Xmx możesz skonfigurować więcej pamięci dla twojej JVM. Aby upewnić się, że nie'wyciekasz lub marnujesz pamięć. Zrób zrzut sterty i użyj Eclipse Memory Analyzer do przeanalizowania zużycia pamięci.

Komentarze (1)