Подтвердить что ты не робот

Зачем нужен пилообразный график?

Когда я запускаю приведенный ниже код (используя netbeans), выделенный размер кучи изменяется в пилообразной форме. Я прикрепляю захват от jVisualVM, который показывает используемый кучевой график в пилообразной форме. Программа представляет собой простой бесконечный цикл печать "lol" на выводе.

class one{
    static int i=0;
    public static void main(String a[]){
        while(i<10){
            System.out.println("lol");
        }
    }
}

enter image description here Может ли кто-нибудь объяснить причину формы графика используемой кучи?

ps: это происходит, даже если я запускаю его без использования NetBeans, поэтому он несколько не связан с netbeans...

4b9b3361

Ответ 1

Пильный рисунок в использовании кучи можно объяснить тем, что при вызове вызова System.out.println создается несколько локальных переменных. В частности, в Oracle/Sun JRE несколько экземпляров HeapCharBuffer создаются в молодом поколении, как указано в следующем снимке, полученном с использованием профилировщика памяти VisualVM:

Visual VM - Memory snapshot

Интересный бит - количество живых объектов, которые присутствуют в куче. Пилообразный рисунок получается из цикла сбора мусора молодого поколения, который возникает, когда пространство эден заполняется; поскольку в программе нет тяжелой вычислительной активности, JVM может выполнять несколько итераций цикла, в результате чего заполняется пространство eden (размером 4 МБ). Последующий цикл сбора молодого поколения затем очищает большую часть мусора; это почти всегда все пространство eden, если только объекты еще не используются, о чем свидетельствует следующая следа gc, полученная из VisualVM:

Visual VM GC probes

Таким образом, поведение пилообразного паттерна может быть объяснено серией распределений объектов в быстрой последовательности, которые заполняют пространство эден, вызывая цикл сбора мусора молодого поколения; этот процесс циклически повторяется без каких-либо задержек, поскольку основной процесс JVM не вытесняется другим процессом, а основной поток в JVM, который отвечает за распределение объектов, также не вытесняется другим потоком.

Ответ 2

Любой процесс, распределяющий объекты с регулярной скоростью, приведет к постоянному увеличению потребления памяти кучи, а затем мгновенным падениям, когда сборщик мусора собирает ненужные объекты, что приводит к тому, что пилообразная форма.

В случае, если вы задаетесь вопросом, почему ваш Java-процесс сохраняет выделенную память при записи на System.out, имейте в виду, что другие потоки (например, одна из которых загружает текущую статистику памяти в JVisualVM) могут быть теми, которые выделяют память.

Ответ 3

Там может быть много мест, и это, вероятно, зависит от реализации. По крайней мере, возможны следующие (но все это просто спекуляция)

  • где-то в стеке потоков под System.out.println имеется распределение байтового массива (учитывая, что одним из основных методов выходного потока является запись (bytes [] b, int off, int len) )

  • это служебные данные, используемые используемым программным обеспечением мониторинга (я его не использовал)

  • он накладные расходы в VM netbeans, где он заканчивает показывать вывод

Ответ 4

Фактически jVisualVM вызывает дополнительное выделение объекта. jVisualVM и jconsole используют расширения Java Management Extensions. Прикрепление к запущенному приложению и запрос JVM-метрик, вызывающих создание дополнительных объектов. Вы можете проверить это, добавив к вашему программному вызову

Runtime.getRuntime().freeMemory() 

который сообщает о свободной памяти в куче JVM. Он покажет [почти] отсутствие изменения памяти, запустив ваш код, но как только вы подключите jVisualVM к вашей программе, вы увидите увеличение использования памяти.