Zagadka z Java Memory

Ostatnia zagadka okazała się bardzo łatwa. Zatem dziś pora na nieco trudniejszą i ciekawszą.

Oto kod zagadki.

Po skompilowaniu i uruchomieniu powyższego kodu otrzymujemy java.lang.OutOfMemoryError:

Natomiast jeśli odkomentujemy linie 10-12, skompilujemy i uruchomimy program ponownie, to błąd braku pamięci się nie pojawi.
Jak to jest, że JVM słucha się Baristy? 🙂

4 komentarze to “Zagadka z Java Memory”

  • dembol pisze:

    Generalnie działający kod można uprościć do poniższej postaci, więc pierwsze, błędne podejrzenie, że to Barista czaruje i nakazuje JVM poprawne działanie są wyssane z palca :p

    Tak jak w poprzedniej zagadce spójrzmy na zdekompilowany kod metody go(). Najpierw bez deklaracji zmiennej i po anonimowym bloku:

    Widzimy, że instrukcje 0-6 odpowiadają za blok anonimowy czyli w naszym przypadku alokację tablicy bajtów i zapis referencji na stosie na pozycji 1. Instrukcje 7-13 odpowiadają z kolei za alokację tablicy bajtów i zapis nowej referencji na stos, także na pozycję 1. W momencie alokacji (instrukcja 11) na stosie istnieje jednak stara referencja do zmiennej bytes1, co uniemożliwia mechanizmowi gc zwolnienie pamięci (mimo, iż zmienna zadeklarowana jest w bloku anonimowym).

    Spójrzmy co się stanie po dodani deklaracji jakiejś zmiennej po bloku anonimowym:

    Linie 7 i 8 powinny dać odpowiedź. Odpowiadają one za załadowanie stałej dla zmiennej i i odłożenie jej wartości na stosie na tej samej pozycji gdzie zapisana jest referencja do tablicy bytes1. Alokacja zmiennej i powoduje więc nadpisanie referencji do starej tablicy bajtów. Dzięki temu instrukcja w linii 13 powoduje uruchomienie gc, zwolnienie pamięci (bo nie istnieje już silna referencja do bytes1) i alokację nowej tablicy bytes2.

  • Karol 'JavAgnostic' Ciba pisze:

    Próbujesz stworzyć dwie tablice o sumarycznej wielkości 1.2 zarezerwowana pamięć? A GC nie ma z jakiegoś powodu możliwości wstrzelenia się między kończący się blok (i zniknięcie zmiennej bytes1 ze scopea) a tworzenie nowej tablicy?

  • wolf pisze:

    ogolnie wystarczylo odkomentowac tylko linijke 10 i 12, efekt ten sam, tyle ze bez baristy 😉

Leave a Reply

Szukaj
Facebook
Prenumerata

Podaj adres email aby otrzymywać info o nowych wpisach.

Kategorie