DEV Community

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

Posted on

1

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 всегда будет достаточно печенья для всех! 🍪

Image of Datadog

How to Diagram Your Cloud Architecture

Cloud architecture diagrams provide critical visibility into the resources in your environment and how they’re connected. In our latest eBook, AWS Solution Architects Jason Mimick and James Wenzel walk through best practices on how to build effective and professional diagrams.

Download the Free eBook

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more