DEV Community

Cover image for Java и Тайна Исчезающей Памяти!
Olga Lugacheva
Olga Lugacheva

Posted on

Java и Тайна Исчезающей Памяти!

В волшебной стране Java Land жил маленький робот по имени JVM-bot. У JVM-bot была очень важная работа: следить за памятью! Дело в том, что память в Java Land была как большая банка с печеньем, и все хотели получить свою долю! Поэтому JVM-bot должен был следить за тем, чтобы всем хватало.

Волшебные индикаторы: totalMemory, freeMemory и maxMemory!

У JVM-bot было три специальных индикатора - инструменты, чтобы следить за всей памятью:

memory jars

totalMemory — Этот индикатор показывал JVM-bot, сколько печенья (или памяти) он уже держит. Этот метод показывает текущее количество памяти, выделенной JVM, что полезно для понимания текущей нагрузки. По сути, totalMemory — это “бюджет” памяти, который у нас уже есть в кармане, чтобы использовать.
freeMemory — Этот говорил ему, сколько печенья осталось в его банке (в памяти, которую он уже имел). Этот метод показывает объем памяти, который еще можно использовать в пределах totalMemory. Например, если totalMemory составляет 500 МБ, а freeMemory — 200 МБ, это значит, что 300 МБ уже заняты. Этот метод помогает нам понять, сколько свободной памяти есть прямо сейчас, и когда стоит задуматься об оптимизации.
maxMemory — А это самый большой индикатор из всех! Он показывал максимальное количество печенья, которое JVM-bot мог когда-либо иметь. Если он был полон, больше печенья добавить нельзя! Например, если у вас максимум установлен на 1024 МБ, это верхний предел, и после его достижения JVM начнет использовать виртуальное печенье (память), что заметно снизит производительность.

memory structure
Вот пример кода, показывающий, как JVM-bot мог использовать эти индикаторы:

public class MemoryExample {
    public static void main(String[] args) {
        Runtime runtime = Runtime.getRuntime();

        // Получаем текущую память
        long totalMemory = runtime.totalMemory(); // Общее количество памяти
        long freeMemory = runtime.freeMemory();   // Свободная память
        long maxMemory = runtime.maxMemory();     // Максимально доступная память

        System.out.println("Общая память: " + totalMemory + " байт");
        System.out.println("Свободная память: " + freeMemory + " байт");
        System.out.println("Максимальная память: " + maxMemory + " байт");
    }
}

Enter fullscreen mode Exit fullscreen mode

JVM-bot любил думать о себе как о стражнике печенья (памяти), используя свои индикаторы, чтобы следить за драгоценными крошками, оставшимися позади.

Вход: Озорные Гремлины Алгоритмов!

В один солнечный день JVM-bot просто занимался своими делами, следя за своими индикаторами, когда вдруг... БАЦ! Появилась кучка шустрых маленьких Гремлинов Алгоритмов! Эти гремлины любили печенье так же, как и JVM-bot, и они были голодны!

Они начали поглощать печенье JVM-bot, откусывая по кусочку здесь и там. Индикатор freeMemory у JVM-bot начал быстро падать, когда гремлины съедали печенье!

cookie gremllins

«О нет!» — воскликнул JVM-bot, потирая свою роботизированную голову. «Если эти гремлины съедят слишком много печенья, не останется достаточно для остальных в Java Land!»

Измерение Аппетитов Гремлинов

У JVM-bot возникла блестящая идея! Он использует свои индикаторы памяти, чтобы узнать, сколько печенья гремлины съедают.

Сначала JVM-bot заглянул в freeMemory, чтобы проверить, сколько печенья у него осталось до того, как гремлины начали лакомиться.

long initialFreeMemory = runtime.freeMemory();
System.out.println("Свободная память перед едой гремлинов: " + initialFreeMemory + " байт");

Enter fullscreen mode Exit fullscreen mode

Затем он сказал: «Ладно, Гремлины, посмотрим, на что вы способны!» и позволил им бегать на воле, откусывая печенье.

После того как гремлины наелись, JVM-bot проверил freeMemory снова:

long remainingFreeMemory = runtime.freeMemory();
System.out.println("Свободная память после еды гремлинов: " + remainingFreeMemory + " байт");

Enter fullscreen mode Exit fullscreen mode

Наконец, JVM-bot провел вычисления, чтобы выяснить, сколько печенья пропало. Это была память, которую гремлины проглотили!

long consumedMemory = initialFreeMemory - remainingFreeMemory;
System.out.println("Съеденная память: " + consumedMemory + " байт");

Enter fullscreen mode Exit fullscreen mode

Большая Красная Кнопка "GC" - Тайное Оружие JVM-bot!

GC
И, наконец, у JVM-bot была большая красная кнопка с надписью GC (сокращение от «Сборка Мусора», конечно!). Это был его экстренный инструмент для очистки печенья. Если дела выходили из-под контроля и гремлины оставляли крошки повсюду, JVM-bot нажимал эту кнопку, и - ВУП! - все крошки исчезали, оставляя JVM-bot с чистой, свежей памятью снова.

Пример кода для вызова сборщика мусора:

System.gc(); // Запускаем сборщик мусора

Enter fullscreen mode Exit fullscreen mode

Советы от JVM-bot: Как Держать Гремлинов Памяти Под Контролем!

Чтобы память оставалась в безопасности, у JVM-bot есть несколько хитростей:

  • Нажмите кнопку GC перед измерением, чтобы не осталось лишних крошек. Очистка мусора перед замерами помогает получить более точные результаты. Это, конечно, не всегда нужно, но для точности измерений — полезно.

  • Не измеряйте слишком часто! JVM-bot измеряет только тогда, когда это действительно необходимо (избегайте замеров в цикле), иначе его индикаторы могут износиться. Слишком частое обращение к памяти через Runtime может создавать небольшие задержки. Вместо этого делайте единичные замеры в начале и конце алгоритма.

Как измерить потребление памяти алгоритмом?

Algo consumption
Чтобы измерить, сколько памяти занимает выполнение определенной части кода, например, алгоритма, нам нужно немного хитрости:

Замеряем начальную память перед выполнением кода.
Выполняем наш алгоритм.
Замеряем память после выполнения.
Находим разницу между замерами.
Пример кода ниже продемонстрирует, как это можно сделать:

public class MemoryUsageExample {
    public static void main(String[] args) {
        Runtime runtime = Runtime.getRuntime();

        // Очистка памяти перед замером
        runtime.gc();

        // Замеряем начальную память
        long memoryBefore = runtime.totalMemory() - runtime.freeMemory();

        // Выполнение алгоритма
        int[] largeArray = new int[10_000_000]; // Просто создаем большой массив
        for (int i = 0; i < largeArray.length; i++) {
            largeArray[i] = i;
        }

        // Замеряем конечную память
        long memoryAfter = runtime.totalMemory() - runtime.freeMemory();

        // Потребление памяти нашим алгоритмом
        long memoryUsed = memoryAfter - memoryBefore;

        System.out.println("Память использованная алгоритмом: " + memoryUsed + " байт");
    }
}

Enter fullscreen mode Exit fullscreen mode

Итак, JVM-bot стал героем Java Land, защищая печенье (память) для всех, независимо от того, сколько гремлинов пытались его съесть. Помните: с JVM-bot и его индикаторами памяти в Java Land всегда будет достаточно печенья для всех! 🍪

Top comments (0)