CodeGym /Kursy /JAVA 25 SELF /Narzędzia analizy pamięci: jmap, jvisualvm

Narzędzia analizy pamięci: jmap, jvisualvm

JAVA 25 SELF
Poziom 64 , Lekcja 3
Dostępny

1. jmap: magia wiersza poleceń

Automatyczny odśmiecacz (garbage collector) — to oczywiście świetna sprawa. Ale nawet aplikacje Java mogą „przeciekać” (OutOfMemoryError), działać wolno lub nagle zwalniać z powodu niewłaściwego użycia pamięci. Przyczyny mogą być różne:

  • Wyciek pamięci (memory leaks): obiekty, które powinny zostać usunięte, nadal „żyją”.
  • Zbyt duże ilości danych w kolekcjach.
  • Błędy w logice cache’owania.
  • Niewyzwalniane zasoby (np. strumienie, pliki).

Twoje zadanie — nauczyć się szybko znajdować takie problemy. W przeciwnym razie ryzykujesz, że zostaniesz nie programistą, a „twórcą bugów”!

Czym jest jmap?

jmap to narzędzie wchodzące w skład standardowego pakietu JDK. Pozwala uzyskać „zrzut” (heap dump) pamięci działającego procesu Javy. Taki zrzut można potem otworzyć w innych narzędziach i sprawdzić, jakie obiekty zajmują pamięć, ile ich jest i kto się do nich odwołuje.

Heap dump to jak zdjęcie twojej sterty: wszystkie obiekty, które się w niej znajdują, ich typy, powiązania i rozmiary.

Jak używać jmap

Znajdź PID procesu

Na początek trzeba ustalić identyfikator procesu (PID), w którym działa twoja aplikacja Java. Można to zrobić na kilka sposobów:

Przez jps (kolejne narzędzie z JDK):

jps -l

Zobaczysz listę procesów Javy i ich PID.

Przez Menedżera zadań (Task Manager) lub ps w Linuksie.

Zrób zrzut pamięci

jmap -dump:format=b,file=heap.bin <PID>
  • format=b — format binarny (odpowiedni do analizy).
  • file=heap.bin — nazwa pliku, do którego zostanie zapisany zrzut.
  • <PID> — identyfikator procesu.

Przykład:

jmap -dump:format=b,file=heap.bin 12345

Co zrobić z heap dumpem?
Zrzut zazwyczaj analizuje się w narzędziach graficznych (np. jvisualvm lub Eclipse MAT), bo ręczne szukanie obiektów w pliku binarnym to już wyższa szkoła jazdy i odrobina masochizmu.

Inne możliwości jmap

Podgląd statystyk pamięci:

jmap -heap <PID>

Pokazuje informacje o stercie: rozmiar, używany GC, stan.

Lista klas:

jmap -histo <PID>

Pokazuje statystyki według klas: ile obiektów danego typu i ich łączny rozmiar.

Przykładowy wynik:

# Obiekt Liczba Bajty
1
[C
1200 48000
2
java.lang.String
1000 32000
3
java.util.HashMap
200 12800

To już daje obraz: jeśli nagle masz miliony obiektów jakiegoś typu — jest powód do zastanowienia.

2. jvisualvm: wizualny analizator pamięci

jvisualvm to program graficzny wchodzący w skład JDK (zobacz w katalogu bin). Pozwala podłączać się do lokalnych (a czasem i zdalnych) procesów Javy, monitorować je w czasie rzeczywistym, wykonywać heap dump, oglądać statystyki pamięci, wątków, GC, CPU, a nawet profilować wykonanie kodu.

Jeśli lubisz klikać myszką i oglądać ładne wykresy — to narzędzie jest dla ciebie.

Jak uruchomić jvisualvm

W wierszu poleceń (albo przez skrót w Windows):

jvisualvm

Otworzy się okno, w którym zobaczysz listę wszystkich lokalnych procesów Javy.

Główne funkcje jvisualvm

Monitorowanie pamięci w czasie rzeczywistym

  • Wybierz proces na liście po lewej.
  • Przejdź na kartę Monitor.
  • Zobaczysz wykresy użycia sterty, CPU, liczbę wątków i klas.

Przykład:

jvisualvm-monitor

Heap Dump (zrzut pamięci)

  • Na panelu Monitor kliknij Heap Dump.
  • Po kilku sekundach pojawi się karta z analizą zrzutu.
  • Zobaczysz listę wszystkich klas, liczbę obiektów oraz ich łączny rozmiar.

Wyszukiwanie „ciężkich” obiektów

  • Sortuj według rozmiaru lub liczby.
  • Jeśli widzisz, że jakiś typ (np. ArrayList lub String) zajmuje zbyt dużo pamięci — to powód do dochodzenia.

Analiza referencji (Reference Graph)

  • Kliknij klasę — zobaczysz, kto odwołuje się do obiektów tej klasy.
  • Można dojść do źródła: dlaczego obiekt nie jest usuwany przez garbage collector.

Analiza wątków

  • Karta Threads — pokazuje wszystkie wątki i ich stan.
  • Można wykryć „zawieszone” lub zbyt aktywne wątki.

Profilowanie

  • Karta Profiler — pozwala mierzyć, które metody zajmują najwięcej czasu lub pamięci.
  • To już głęboka analiza, ale do szukania wycieków pamięci wystarczą pierwsze kroki.

3. Praktyka: analizujemy wyciek pamięci

Przykład kodu z wyciekiem

import java.util.ArrayList;
import java.util.List;

public class MemoryLeakDemo {
    // Statyczna kolekcja — klasyka gatunku!
    private static final List<String> bigList = new ArrayList<>();

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 1_000_000; i++) {
            bigList.add("Wiersz numer " + i);
            if (i % 100_000 == 0) {
                System.out.println("Dodano: " + i);
                Thread.sleep(500); // Dajemy czas na analizę
            }
        }
        System.out.println("Gotowe! Nie zamykaj aplikacji, otwórz jvisualvm.");
        Thread.sleep(600_000); // 10 minut — czas na analizę
    }
}

Co się dzieje?

  • Tworzymy statyczną listę i dodajemy do niej milion napisów.
  • Po zakończeniu dodawania program „zawisa” (czeka), abyś mógł podłączyć się do niego narzędziami analizy.

Analiza przez jvisualvm

  1. Uruchom program.
  2. Otwórz jvisualvm i wybierz proces.
  3. Na karcie Monitor obejrzyj wykres pamięci.
    • Jeśli wszystko jest w porządku, pamięć po GC powinna się „zwalniać”.
    • Jeśli jest wyciek, pamięć tylko rośnie.
  4. Wykonaj Heap Dump.
  5. Sprawdź, które obiekty zajmują najwięcej pamięci.
    • W naszym przypadku — java.util.ArrayList i java.lang.String.
  6. Kliknij obiekt — zobacz, kto się do niego odwołuje.
    • Zobaczysz, że to statyczne pole bigList.

Jak to naprawić?

  • Usuwaj zbędne elementy z kolekcji, ograniczaj ich wzrost.
  • Zeruj odwołania do „ciężkich” obiektów, gdy nie są już potrzebne.
  • Nie trzymaj dużych kolekcji w static, jeśli nie są potrzebne cały czas.

4. Inne narzędzia: Eclipse MAT, jconsole

Eclipse Memory Analyzer (MAT)

Eclipse MAT to bezpłatne, ale bardzo mocne narzędzie do analizy heap dump. Pozwala zobaczyć, jakie obiekty zajmują pamięć i które z nich utrzymują inne — tak zwany retained set. Dzięki temu można precyzyjnie ustalić, gdzie kryje się wyciek.

Narzędzie potrafi budować szczegółowe raporty o podejrzanych obiektach (leak suspects) i spokojnie radzi sobie nawet z gigantycznymi zrzutami o rozmiarze kilku gigabajtów.

Działa to prosto: wykonujesz zrzut pamięci za pomocą jmap lub jvisualvm, otwierasz go w MAT, klikasz przycisk Leak Suspects Report — i dostajesz gotowy raport z już podświetlonymi potencjalnymi problemami.

jconsole

jconsole to proste i wygodne narzędzie do obserwowania JVM w czasie rzeczywistym. Pokazuje, ile pamięci jest używane, jak obciążony jest procesor, ile wątków pracuje i jak zachowuje się garbage collector.

W odróżnieniu od bardziej zaawansowanych narzędzi, takich jak VisualVM, jconsole nie analizuje heap dump, ale świetnie nadaje się do szybkiej diagnostyki — kiedy trzeba jednym rzutem oka zrozumieć, co dzieje się wewnątrz aplikacji.

5. Typowe błędy przy analizie pamięci

Błąd nr 1: Zrzucasz pamięć nie tego procesu. Często na maszynie działa wiele aplikacji Java i można pomylić PID. Sprawdź przez jps i upewnij się, że analizujesz właśnie swój program.

Błąd nr 2: Oczekujesz „wycieku” tam, gdzie go nie ma. GC może nie usuwać obiektów od razu — czasem pamięć „zwalnia się” dopiero po Full GC. Nie panikuj, jeśli po jednej iteracji pamięć się nie zwolniła — spójrz na trend.

Błąd nr 3: Nie uwzględniasz wpływu obiektów statycznych/cache’owanych. Wiele wycieków wynika z tego, że obiekty są przechowywane w polach static lub globalnych kolekcjach. Sprawdzaj, kto odwołuje się do „ciężkich” obiektów — to często static.

Błąd nr 4: Nie używasz profilowania w czasie działania. Heap dump to dobrze, ale czasem ważne jest obserwować wzrost pamięci w czasie (wykresy w jvisualvm). Jeśli pamięć stabilnie rośnie — jest powód do dochodzenia.

Błąd nr 5: Nie usuwasz nasłuchiwaczy/obsługi zdarzeń. Jeśli zasubskrybowałeś zdarzenie, ale się nie wypisałeś — obiekt będzie „żył” w pamięci, nawet jeśli już go nie używasz.

Wskazówka: Nie bój się eksperymentować z narzędziami! Rób zrzuty, oglądaj wykresy, klikaj obiekty — tylko tak nauczysz się „czuć” pamięć swojej aplikacji i szybko znajdować problemy.

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION