JavaRush /Курси /JAVA 25 SELF /Інструменти аналізу пам’яті: jmap, jvisualvm

Інструменти аналізу пам’яті: jmap, jvisualvm

JAVA 25 SELF
Рівень 64 , Лекція 3
Відкрита

1. jmap: командна магія

Автоматичний збирач сміття — це, звісно, чудово. Але навіть Java‑застосунки можуть «підтікати» (OutOfMemoryError), працювати повільно або неочікувано гальмувати через некоректне використання пам’яті. Причини можуть бути різними:

  • Витоки пам’яті (memory leaks): об’єкти, які мали бути видалені, продовжують «жити».
  • Надто великі обсяги даних у колекціях.
  • Помилки в логіці кешування.
  • Незвільнені ресурси (наприклад, потоки, файли).

Ваше завдання — навчитися швидко виявляти такі проблеми. Інакше ви ризикуєте стати не програмістом, а «розробником багів»!

Що таке jmap?

jmap — це утиліта, що входить до стандартного комплекту JDK. Вона дає змогу отримати «знімок» (heap dump) пам’яті працюючого Java‑процесу. Цей знімок можна потім відкрити в інших інструментах і подивитися, які об’єкти займають пам’ять, скільки їх і хто на них посилається.

Heap dump — це як фотографія вашої купи: усі об’єкти, що в ній є, їхні типи, зв’язки та розміри.

Як використовувати jmap

Знайдіть PID процесу

Спершу потрібно дізнатися ідентифікатор процесу (PID), у якому працює ваш Java‑застосунок. Це можна зробити різними способами:

Через jps (ще одна утиліта з JDK):

jps -l

Ви побачите список Java‑процесів і їхні PID.

Через Диспетчер завдань (Task Manager) або ps у Linux.

Зніміть дамп пам’яті

jmap -dump:format=b,file=heap.bin <PID>
  • format=b — бінарний формат (підходить для аналізу).
  • file=heap.bin — ім’я файла, куди буде збережено дамп.
  • <PID> — ідентифікатор процесу.

Приклад:

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

Що робити з heap dump?
Зазвичай дамп аналізують у графічних інструментах (наприклад, jvisualvm або Eclipse MAT), тому що вручну шукати об’єкти в бінарному файлі — це вже вищий пілотаж і трохи мазохізм.

Інші можливості jmap

Перегляд статистики пам’яті:

jmap -heap <PID>

Показує інформацію про купу: розмір, використовуваний GC, стан.

Список класів:

jmap -histo <PID>

Показує статистику за класами: скільки об’єктів якого типу, загальний розмір.

Приклад виведення:

# Об’єкт Кількість Байти
1
[C
1200 48000
2
java.lang.String
1000 32000
3
java.util.HashMap
200 12800

Це вже дає уявлення: якщо у вас раптом мільйони об’єктів певного типу — є привід замислитися.

2. jvisualvm: візуальний аналізатор пам’яті

jvisualvm — це графічна програма, що входить до JDK (подивіться в папці bin). Вона дає змогу під’єднуватися до локальних (і іноді віддалених) Java‑процесів, моніторити їх у реальному часі, знімати heap dump, дивитися статистику щодо пам’яті, потоків, GC, CPU та навіть профілювати виконання коду.

Якщо ви любите клікати мишею і дивитися гарні графіки — це ваш інструмент.

Як запустити jvisualvm

У командному рядку (або через ярлик у Windows):

jvisualvm

Відкриється вікно, де ви побачите список усіх локальних Java‑процесів.

Основні функції jvisualvm

Моніторинг пам’яті в реальному часі

  • Виберіть процес у списку ліворуч.
  • Перейдіть на вкладку Monitor.
  • Ви побачите графіки використання heap, CPU, а також кількість потоків і класів.

Приклад:

jvisualvm-monitor

Heap Dump (Знімок пам’яті)

  • На панелі Monitor натисніть Heap Dump.
  • За кілька секунд з’явиться вкладка з аналізом дампа.
  • Ви побачите список усіх класів, кількість об’єктів, їхній загальний розмір.

Пошук «важких» об’єктів

  • Сортуйте за розміром або кількістю.
  • Якщо бачите, що якийсь тип (наприклад, ArrayList або String) займає надто багато пам’яті — це привід для розслідування.

Аналіз посилань (Reference Graph)

  • Клікніть на клас — побачите, хто посилається на об’єкти цього класу.
  • Можна «докопатися» до кореня: чому об’єкт не видаляється збирачем сміття.

Аналіз потоків

  • Вкладка Threads — показує всі потоки, їхній стан.
  • Можна виявити «завислі» або надто активні потоки.

Профілювання

  • Вкладка Profiler — дає змогу вимірювати, які методи займають найбільше часу або пам’яті.
  • Це вже глибокий аналіз, але для пошуку витоків пам’яті достатньо перших кроків.

3. Практика: аналізуємо витік пам’яті

Приклад коду з витоком

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

public class MemoryLeakDemo {
    // Статична колекція — класика жанру!
    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("Рядок номер " + i);
            if (i % 100_000 == 0) {
                System.out.println("Додано: " + i);
                Thread.sleep(500); // Даємо час для аналізу
            }
        }
        System.out.println("Готово! Не закривайте застосунок, відкрийте jvisualvm.");
        Thread.sleep(600_000); // 10 хвилин — час на аналіз
    }
}

Що відбувається?

  • Ми створюємо статичний список і додаємо до нього мільйон рядків.
  • Після завершення додавання програма «зависає» (чекає), щоб ви могли під’єднатися до неї інструментами аналізу.

Аналіз через jvisualvm

  1. Запустіть програму.
  2. Відкрийте jvisualvm і виберіть процес.
  3. На вкладці Monitor подивіться графік пам’яті.
    • Якщо все добре, пам’ять після GC має «звільнятися».
    • Якщо є витік, пам’ять лише зростає.
  4. Зробіть Heap Dump.
  5. Подивіться, які об’єкти займають найбільше пам’яті.
    • У нашому випадку — java.util.ArrayList і java.lang.String.
  6. Клікніть на об’єкт — подивіться, хто на нього посилається.
    • Побачите, що це статичне поле bigList.

Як виправити?

  • Видаляйте непотрібні елементи з колекцій, обмежуйте їхній ріст.
  • Обнуляйте посилання на важкі об’єкти, коли вони вже не потрібні.
  • Не тримайте великі колекції у static, якщо вони не потрібні постійно.

4. Інші інструменти: Eclipse MAT, jconsole

Eclipse Memory Analyzer (MAT)

Eclipse MAT — це безкоштовний, але водночас потужний інструмент для аналізу heap dump. За його допомогою можна побачити, які об’єкти займають пам’ять і які з них утримують інші — так званий retained set. Це дає змогу точно визначити, де ховається витік.

Інструмент уміє будувати докладні звіти щодо підозрілих об’єктів (leak suspects) і спокійно справляється навіть із гігантськими дампами розміром у кілька гігабайтів.

Працює все просто: ви знімаєте дамп пам’яті за допомогою jmap або jvisualvm, відкриваєте його в MAT, натискаєте кнопку Leak Suspects Report — і отримуєте готовий звіт, у якому вже підсвічено потенційні проблеми.

jconsole

jconsole — це простий і зручний інструмент для спостереження за JVM у реальному часі. Він показує, скільки пам’яті використовується, наскільки завантажений процесор, скільки потоків працює та як поводиться збирач сміття.

На відміну від більш просунутих інструментів на кшталт VisualVM, jconsole не аналізує heap dump, зате чудово підходить для швидкої діагностики — коли потрібно з першого погляду зрозуміти, що зараз відбувається всередині застосунку.

5. Типові помилки під час аналізу пам’яті

Помилка № 1: знімаєте дамп не того процесу. Часто на машині запущено багато Java‑застосунків, і можна переплутати PID. Перевіряйте за допомогою jps і переконайтеся, що аналізуєте саме вашу програму.

Помилка № 2: очікуєте побачити «витік» там, де його немає. GC може не одразу видаляти об’єкти — іноді пам’ять «відпускається» лише після Full GC. Не панікуйте, якщо після однієї ітерації пам’ять не звільнилася — подивіться на тенденцію.

Помилка № 3: не враховуєте вплив статичних/кешованих об’єктів. Багато витоків пов’язані з тим, що об’єкти зберігаються в static-полях або глобальних колекціях. Перевіряйте, хто посилається на «важкі» об’єкти — це часто static.

Помилка № 4: не використовуєте профілювання в динаміці. Heap dump — це добре, але інколи важливо дивитися на зростання пам’яті в часі (графіки в jvisualvm). Якщо пам’ять стабільно зростає — є привід для розслідування.

Помилка № 5: не видаляєте слухачів/обробники подій. Якщо ви підписалися на подію, але не відписалися — об’єкт «житиме» в пам’яті, навіть якщо ви його більше не використовуєте.

Порада: Не бійтеся експериментувати з інструментами! Знімайте дампи, дивіться графіки, клікайте по об’єктах — тільки так ви навчитеся «відчувати» пам’ять своєї програми й швидко знаходити проблеми.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ