Łapanie Javy.lang.OutOfMemoryError?

Dokumentacja dla java.lang.Error mówi:

Błąd jest podklasą Throwable, która wskazuje na poważne problemy, których rozsądna aplikacja nie powinna próbować złapać

Ale ponieważ java.lang.Error jest podklasą java.lang.Throwable, mogę złapać tego typu Throwable.

Rozumiem, dlaczego to nie jest dobry pomysł, aby złapać tego rodzaju wyjątek. O ile dobrze rozumiem, jeśli zdecydujemy się go złapać, obsługa łapania nie powinna przydzielać żadnej pamięci samodzielnie. W przeciwnym razie OutOfMemoryError będzie znowu rzucony.

Więc moje pytanie brzmi:
  1. czy są jakieś realne scenariusze, kiedy łapanie java.lang.OutOfMemoryError może być dobrym pomysłem?
  2. jeśli zdecydujemy się na catch java.lang.OutOfMemoryError, skąd mamy pewność, że obsługa catch nie przydziela żadnej pamięci samodzielnie (żadnych narzędzi lub najlepszych praktyk)?
Author: Michael Petrotta, 2010-04-21

14 answers

Zgadzam się i nie zgadzam się z większością odpowiedzi tutaj.

Istnieje wiele scenariuszy, w których możesz chcieć złapać OutOfMemoryError i z mojego doświadczenia (na Windows i Solaris JVMs), tylko bardzo rzadko jest OutOfMemoryError death-knell do JVM.

Jest tylko jeden dobry powód, aby złapać OutOfMemoryError i to jest zamykanie z wdziękiem, czyste uwalnianie zasobów i rejestrowanie przyczyny awarii najlepiej jak potrafisz(jeśli jest to nadal możliwe).

Ogólnie rzecz biorąc, OutOfMemoryError występuje z powodu alokacji pamięci blokowej, która nie może być zaspokojona z pozostałych zasobów sterty.

Po wyrzuceniu Error sterta zawiera taką samą ilość przydzielonych obiektów jak przed nieudaną alokacją i teraz jest czas, aby upuścić odwołania do obiektów w czasie wykonywania, aby zwolnić jeszcze więcej pamięci, która może być wymagana do czyszczenia. W takich przypadkach może być nawet możliwe kontynuowanie, ale to z pewnością byłby zły pomysł, ponieważ nigdy nie można być w 100% pewnym, że JVM jest w stanie naprawy.

Demonstracja, że {[2] } nie oznacza, że JVM nie ma pamięci w bloku catch:

private static final int MEGABYTE = (1024*1024);
public static void runOutOfMemory() {
    MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
    for (int i=1; i <= 100; i++) {
        try {
            byte[] bytes = new byte[MEGABYTE*500];
        } catch (Exception e) {
            e.printStackTrace();
        } catch (OutOfMemoryError e) {
            MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
            long maxMemory = heapUsage.getMax() / MEGABYTE;
            long usedMemory = heapUsage.getUsed() / MEGABYTE;
            System.out.println(i+ " : Memory Use :" + usedMemory + "M/" + maxMemory + "M");
        }
    }
}

Wyjście tego kodu:

1 : Memory Use :0M/247M
..
..
..
98 : Memory Use :0M/247M
99 : Memory Use :0M/247M
100 : Memory Use :0M/247M

Jeśli uruchamiam coś krytycznego, zazwyczaj łapię Error, loguję to do syserra, a następnie loguję za pomocą wybranej przeze mnie struktury logowania, a następnie przystępuję do zwalniania zasobów i zamykania w czysty sposób. Co gorszego może się stać? JVM i tak umiera (lub już nie żyje), a łapiąc Error jest przynajmniej szansa na sprzątanie.

Zastrzeżenie polega na tym, że musisz celować w wyłapywanie tego typu błędów tylko w miejscach, w których możliwe jest czyszczenie. Nie koc catch(Throwable t) {} wszędzie lub bzdury w ten sposób.

 66
Author: Chris,
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-06-26 18:36:53

Ty możesz wyzdrowieć:

package com.stackoverflow.q2679330;

public class Test {

    public static void main(String... args) {
        int size = Integer.MAX_VALUE;
        int factor = 10;

        while (true) {
            try {
                System.out.println("Trying to allocate " + size + " bytes");
                byte[] bytes = new byte[size];
                System.out.println("Succeed!");
                break;
            } catch (OutOfMemoryError e) {
                System.out.println("OOME .. Trying again with 10x less");
                size /= factor;
            }
        }
    }

}
Ale czy to ma sens? Co jeszcze chciałbyś zrobić? Dlaczego początkowo przydzielasz tyle pamięci? Czy mniej pamięci też jest OK? Dlaczego już tego nie wykorzystasz? A jeśli to nie jest możliwe, dlaczego po prostu nie dać JVM więcej pamięci od samego początku?

Wróć do pytań:

1: czy przy łapaniu Javy są jakieś realne scenariusze słowne?lang.OutOfMemoryError może być dobrym pomysł?

Nic nie przychodzi mi do głowy.

2: jeśli złapiemy Javę.lang.OutOfMemoryError skąd mamy pewność, że program obsługi catch nie przydziela żadnej pamięci samodzielnie (żadnych narzędzi lub najlepszych praktyk)?

Zależy od tego, co spowodowało OOME. Jeśli zostanie zadeklarowana poza try blokiem i stanie się krok po kroku, Twoje szanse są niewielkie. Możesz Może chcesz zarezerwować trochę miejsca na pamięci wcześniej:

private static byte[] reserve = new byte[1024 * 1024]; // Reserves 1MB.

A następnie ustaw go na zero podczas OOME:

} catch (OutOfMemoryException e) {
     reserve = new byte[0];
     // Ha! 1MB free!
}

Oczywiście to wszystko bez sensu ;) po prostu daj JVM wystarczającą ilość pamięci, jakiej wymaga Twoje zastosowanie. W razie potrzeby uruchom profiler.

 27
Author: BalusC,
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-04-21 01:03:05

Ogólnie rzecz biorąc, to zły pomysł, aby spróbować złapać i odzyskać z OOM.

  1. OOME mógł być również wyświetlany w innych wątkach, w tym wątkach, o których aplikacja nawet nie wie. Wszelkie takie wątki będą teraz martwe, a wszystko, co czekało na powiadomienie, może utknąć na zawsze. Krótko mówiąc, twoja aplikacja może być nieuleczalnie zepsuta.

  2. Nawet jeśli uda Ci się odzyskać, twój JVM może nadal cierpieć z głodu, a Twój w rezultacie aplikacja będzie działać fatalnie.

Najlepszą rzeczą do zrobienia z OOME jest pozwolić JVM umrzeć.

(zakłada to, że JVM umiera. Na przykład Oom w wątku Servleta Tomcat nie zabija JVM, a to prowadzi do tego, że Tomcat przechodzi w stan katatoniczny, w którym nie odpowiada na żadne żądania ... nawet nie prosi o ponowne uruchomienie.)

EDIT

Nie mówię, że to zły pomysł złapać OOM w ogóle. Na problemy pojawiają się, gdy następnie próbujesz odzyskać z OOME, celowo lub przez nadzór. Za każdym razem, gdy złapiesz OOM (bezpośrednio, lub jako podtyp błędu lub Throwable), powinieneś albo go zrehabilitować, albo zaaranżować wyjście aplikacji / JVM.

Na bok: sugeruje to, że aby uzyskać maksymalną wytrzymałość w obliczu Oom, aplikacja powinna użyć wątku .setDefaultUncaughtExceptionHandler () aby ustawić funkcję obsługi, która spowoduje zamknięcie aplikacji w przypadku OOME, no ważne, na jaką nić rzuca się OOME. Byłbym zainteresowany opiniami na ten temat ...

Jedyny inny scenariusz jest wtedy, gdy wiesz na pewno że OOM nie spowodował żadnych szkód ubocznych; tzn. wiesz:

  • co konkretnie spowodowało OOME,
  • co aplikacja robiła w tym czasie, i że można po prostu odrzucić to obliczenie i
  • że (mniej więcej) równoczesne OOME nie mogło wystąpić na innym nić.

Istnieją aplikacje, w których możliwe jest poznanie tych rzeczy, ale dla większości aplikacji nie można mieć pewności, że kontynuacja po OOME jest Bezpieczna. Nawet jeśli empirycznie "działa"przy próbie.

(problem polega na tym, że wymagany jest formalny dowód, aby pokazać, że konsekwencje "przewidywanych" Oomów są bezpieczne, i że "nieprzewidziane" OOME nie mogą wystąpić pod kontrolą try / catch OOME.)

 14
Author: Stephen C,
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-02-26 00:56:42

Tak, istnieją realne scenariusze. Oto moje: muszę przetwarzać zbiory danych bardzo wielu elementów na klastrze z ograniczoną pamięcią na węzeł. Dane instancje JVM przechodzą przez wiele elementów jeden po drugim, ale niektóre z nich są zbyt duże, aby przetworzyć je na klastrze: mogę wyłapać OutOfMemoryError i zwrócić uwagę, które elementy są zbyt duże. Później mogę ponownie uruchomić tylko duże przedmioty na komputerze z większą ilością pamięci RAM.

(ponieważ jest to pojedyncza wielogigabajtowa alokacja tablicy, która się nie powiedzie, JVM jest nadal w porządku po wyłapaniu błędu i jest wystarczająco dużo pamięci, aby przetworzyć inne elementy.)

 11
Author: Michael Kuhn,
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-01-20 09:43:12

Są zdecydowanie scenariusze, w których złapanie OOME ma sens. IDEA łapie je i wyskakuje okno dialogowe umożliwiające zmianę ustawień pamięci startowej(a następnie kończy się po zakończeniu). Serwer aplikacji może je złapać i zgłosić. Kluczem do tego jest robienie tego na wysokim poziomie w wysyłce, aby mieć rozsądną szansę na uwolnienie kilku zasobów w momencie, w którym łapiesz wyjątek.

Poza powyższym scenariuszem, ogólnie rzecz biorąc wyłapywanie powinno być możliwe do wyrzucenia, a nie tylko konkretnie OOM, i powinno być wykonywane w kontekście, w którym przynajmniej wątek zostanie wkrótce zakończony.

Oczywiście większość razy pamięć jest głodzona i sytuacja nie jest do odzyskania, ale są sposoby, że ma to sens.

 8
Author: Yishai,
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-04-21 02:22:00

Natknąłem się na to pytanie, ponieważ zastanawiałem się, czy to dobry pomysł, aby złapać Ofmemoryerror w moim przypadku. Odpowiadam tutaj częściowo, aby pokazać jeszcze inny przykład, gdy wyłapywanie tego błędu może mieć sens dla kogoś (tj. mnie) i częściowo, aby dowiedzieć się, czy jest to dobry pomysł w moim przypadku rzeczywiście (ze mną jako Uber Junior developer nigdy nie może być zbyt pewien o każdej pojedynczej linii kodu piszę).

W każdym razie pracuję nad aplikacją na Androida, która może być uruchomiona na różne urządzenia o różnych rozmiarach pamięci. Niebezpieczną częścią jest dekodowanie bitmapy z pliku i usuwanie jej w instancji ImageView. Nie chcę ograniczać mocniejszych urządzeń pod względem wielkości dekodowanej bitmapy, ani nie mogę być pewien, że aplikacja nie zostanie uruchomiona na jakimś starożytnym urządzeniu, z którym nigdy nie spotkałem się z bardzo niską pamięcią. Dlatego robię to:

BitmapFactory.Options bitmapOptions = new BitmapFactory.Options(); 
bitmapOptions.inSampleSize = 1;
boolean imageSet = false;
while (!imageSet) {
  try {
    image = BitmapFactory.decodeFile(filePath, bitmapOptions);
    imageView.setImageBitmap(image); 
    imageSet = true;
  }
  catch (OutOfMemoryError e) {
    bitmapOptions.inSampleSize *= 2;
  }
}

W ten sposób udaje mi się dostarczać urządzenia o większej i mniejszej mocy zgodnie z ich, a raczej potrzebami użytkowników i oczekiwania.

 7
Author: Maria,
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-02-28 11:50:30

Tak, prawdziwe pytanie brzmi: "co zamierzasz zrobić w programie obsługi wyjątków?"W przypadku prawie wszystkiego, co przydatne, przydzielisz więcej pamięci. Jeśli chcesz wykonać diagnostykę, gdy wystąpi błąd OutOfMemoryError, możesz użyć Hooka -XX:OnOutOfMemoryError=<cmd> dostarczonego przez maszynę wirtualną HotSpot. Wykona Twoje polecenia, gdy wystąpi OutOfMemoryError i możesz zrobić coś użytecznego poza stertą Javy. Naprawdę chcesz, aby aplikacja nie zabrakło pamięci w pierwszej kolejności, więc dowiedzieć się dlaczego tak się dzieje, to pierwszy krok. Następnie możesz odpowiednio zwiększyć rozmiar sterty MaxPermSize. Oto kilka innych przydatnych haków HotSpot:

-XX:+PrintCommandLineFlags
-XX:+PrintConcurrentLocks
-XX:+PrintClassHistogram

Zobacz pełną listę tutaj

 5
Author: Rob Heiser,
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-04-21 00:41:53

Mam aplikację, która musi odzyskać po awariach OutOfMemoryError, a w programach jednowątkowych zawsze działa, ale czasami nie działa w programach wielowątkowych. Aplikacja jest zautomatyzowanym narzędziem do testowania Javy, które wykonuje wygenerowane sekwencje testowe do maksymalnej możliwej głębokości na klasach testowych. Teraz interfejs użytkownika musi być stabilny, ale silnik testowy może zabraknąć pamięci podczas uprawy drzewa przypadków testowych. Zajmuję się tym za pomocą następującego idiomu kodu w teście silnik:

boolean isOutOfMemory = false;  // flag used for reporting
try {
   SomeType largeVar;
   // Main loop that allocates more and more to largeVar
   // may terminate OK, or raise OutOfMemoryError
}
catch (OutOfMemoryError ex) {
   // largeVar is now out of scope, so is garbage
   System.gc();                // clean up largeVar data
   isOutOfMemory = true;       // flag available for use
}
// program tests flag to report recovery

Działa to za każdym razem w aplikacjach jednowątkowych. Ale ostatnio umieściłem mój silnik testowy w osobnym wątku roboczym z interfejsu użytkownika. Teraz, out of memory może wystąpić arbitralnie w każdym wątku, i nie jest dla mnie jasne, jak go złapać.

Na przykład miałem OOME, gdy klatki animowanego GIFA w moim interfejsie były przełączane przez zastrzeżony wątek, który jest tworzony za kulisami przez klasę swingu, która jest poza moją kontrolą. I had thought that I wcześniej przydzielono wszystkie potrzebne zasoby, ale oczywiście animator alokuje pamięć za każdym razem, gdy pobiera następny obraz. Jeśli ktoś ma pomysł jak poradzić sobie z Oomami wychowanymi w jakimkolwiek wątku, chętnie posłucham.

 4
Author: Tony Simons,
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-31 09:35:07

Jedynym powodem, dla którego mogę wymyślić, dlaczego łapanie błędów OOM może być to, że masz ogromne struktury danych, których już nie używasz, i możesz ustawić na null i zwolnić trochę pamięci. Ale (1) oznacza to, że marnujesz pamięć i powinieneś naprawić swój kod, a nie tylko kuleć po OOME, i (2) nawet gdybyś go złapał, co byś zrobił? OOM może się zdarzyć w dowolnym momencie, potencjalnie pozostawiając wszystko w połowie zrobione.

 2
Author: cHao,
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-04-21 00:10:08

Na pytanie 2 już widzę rozwiązanie, które zaproponowałbym przez BalusC.

  1. Czy istnieją prawdziwe scenariusze słów podczas łapania Javy.lang.OutOfMemoryError może być dobrym pomysłem?

Myślę, że właśnie natknąłem się na dobry przykład. Podczas wysyłania wiadomości przez aplikację awt na stderr jest wyświetlany niezrównany OutOfMemoryError i przetwarzanie bieżącej wiadomości jest zatrzymywane. Ale aplikacja działa! Użytkownik może nadal wydawać inne polecenia nieświadomy poważnych problemów za sceną. Zwłaszcza, gdy nie może lub nie przestrzega standardowego błędu. Więc łapanie wyjątku oom i zapewnienie (lub przynajmniej sugerowanie) restartu aplikacji jest czymś pożądanym.

 2
Author: Jarekczek,
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-07-25 06:50:11

OOME może zostać przechwycone, ale będzie ogólnie bezużyteczne, w zależności od tego, czy JVM jest w stanie zebrać niektóre obiekty po osiągnięciu przechwycenia i ile pamięci sterty zostanie do tego czasu.

Przykład: w moim JVM ten program uruchamia się do zakończenia:

import java.util.LinkedList;
import java.util.List;

public class OOMErrorTest {             
    public static void main(String[] args) {
        List<Long> ll = new LinkedList<Long>();

        try {
            long l = 0;
            while(true){
                ll.add(new Long(l++));
            }
        } catch(OutOfMemoryError oome){         
            System.out.println("Error catched!!");
        }
        System.out.println("Test finished");
    }  
}

Jednak samo dodanie jednej linijki na haczyku pokaże ci o czym mówię:

import java.util.LinkedList;
import java.util.List;

public class OOMErrorTest {             
    public static void main(String[] args) {
        List<Long> ll = new LinkedList<Long>();

        try {
            long l = 0;
            while(true){
                ll.add(new Long(l++));
            }
        } catch(OutOfMemoryError oome){         
            System.out.println("Error catched!!");
            System.out.println("size:" +ll.size());
        }
        System.out.println("Test finished");
    }
}

Pierwszy program działa dobrze, ponieważ po osiągnięciu połowu JVM wykrywa, że lista nie będzie być już używane (wykrywanie to może być również optymalizacją dokonaną w czasie kompilacji). Więc kiedy osiągniemy instrukcję print, pamięć sterty została uwolniona prawie całkowicie, więc teraz mamy szeroki margines manewru, aby kontynuować. To najlepszy przypadek.

Jednakże, jeśli kod jest ułożony tak, jak Lista ll jest używana po przechwyceniu OOME, JVM nie jest w stanie go zebrać. Dzieje się tak w drugim fragmencie. OOME, wyzwalany przez nową długą kreację, zostaje złapany, ale wkrótce jesteśmy tworzenie nowego obiektu (ciąg znaków w linii System.out,println), A sterta jest prawie pełna, więc nowy OOME jest wyrzucany. Jest to najgorszy scenariusz: próbowaliśmy utworzyć nowy obiekt, nie udało nam się, złapaliśmy OOME, tak, ale teraz pierwsza instrukcja wymagająca nowej pamięci sterty (np.: tworzenie nowego obiektu) rzuci nowy OOME. Pomyśl o tym, co jeszcze możemy zrobić w tym momencie z tak małą pamięcią?. Pewnie tylko wychodzi. Stąd bezużyteczne.

Wśród powodów, dla których JVM nie zbiera zasoby, jeden jest naprawdę straszny: dzielony zasób z innymi wątkami również z niego korzystającymi. Każdy z mózgiem może zobaczyć, jak niebezpieczne może być złapanie OOME, jeśli zostanie wstawione na jakiejś nieeksperymentalnej aplikacji jakiegokolwiek rodzaju.

Używam Windows x86 32bits JVM (JRE6). Domyślna pamięć dla każdej aplikacji Java to 64 MB.
 2
Author: Mister Smith,
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-19 07:28:28

Mam tylko scenariusz, w którym złapanie OutOfMemoryError wydaje się mieć sens i wydaje się działać.

Scenariusz: w aplikacji na Androida chcę wyświetlać wiele bitmap w najwyższej możliwej rozdzielczości i chcę móc je płynnie powiększać.

Ze względu na płynne powiększanie, chcę mieć bitmapy w pamięci. Jednak Android ma ograniczenia w pamięci, które są zależne od urządzenia i które są trudne do kontrolowania.

W tej sytuacji może wystąpić OutOfMemoryError podczas czytam bitmapę. Tutaj pomaga, jeśli go złapię, a następnie kontynuuję z niższą rozdzielczością.

 1
Author: Jörg Eisfeld,
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-03-30 19:43:25

Możesz wyłapać wszystko pod Throwable, ogólnie rzecz biorąc powinieneś wyłapywać tylko podklasy WYJĄTKÓW z wyłączeniem RuntimeException (choć duża część programistów również wyłapuje RuntimeException... ale to nigdy nie było intencją projektantów języka).

Gdybyś złapał Moemoryerror, co byś zrobił? Maszyna wirtualna nie ma pamięci, w zasadzie wszystko, co możesz zrobić, to wyjść. Prawdopodobnie nie możesz nawet otworzyć okna dialogowego, aby powiedzieć im, że nie masz pamięci, ponieważ byłoby to weź pamięć : -)

Maszyna wirtualna wyrzuca błąd OutOfMemoryError, gdy rzeczywiście brakuje mu pamięci (wszystkie błędy powinny wskazywać na niemożliwe do odzyskania sytuacje) i naprawdę nie powinno być nic, co można zrobić, aby sobie z tym poradzić.

Musisz dowiedzieć się, dlaczego kończy ci się pamięć (użyj profilera, takiego jak ten w NetBeans) i upewnić się, że nie masz wycieków pamięci. Jeśli nie masz wycieków pamięci, Zwiększ pamięć przydzieloną maszynie wirtualnej.

 0
Author: TofuBeer,
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-04-20 23:24:43
    Zależy jak zdefiniujesz "dobre". Robimy to w naszej błędnej aplikacji internetowej i działa przez większość czasu (na szczęście teraz {[0] }nie dzieje się z powodu niepowiązanej poprawki). Jednak nawet jeśli go złapiesz, nadal może złamać jakiś ważny kod: jeśli masz kilka wątków, alokacja pamięci może się nie udać w każdym z nich. Tak więc, w zależności od twojej aplikacji nadal istnieje 10--90% szansa, że zostanie nieodwracalnie złamana.
  1. o ile rozumiem, ciężki stack odwijanie po drodze unieważni tak wiele odniesień, a tym samym uwolni tyle pamięci, że nie powinno cię to obchodzić.

EDIT: proponuję wypróbować. Powiedzmy, napisz program, który rekurencyjnie wywołuje funkcję, która przydziela stopniowo więcej pamięci. Złap OutOfMemoryError i sprawdź, czy możesz sensownie kontynuować od tego momentu. Z mojego doświadczenia wynika, że będziesz w stanie, choć w moim przypadku stało się to pod serwerem WebLogic, więc może być jakaś czarna magia.

 0
Author: doublep,
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-04-20 23:30:09