Почему пилообразный график? - PullRequest
17 голосов
/ 28 августа 2011

Когда я запускаю приведенный ниже код с использованием NetBeans, график выделенного размера кучи напоминает форму пилообразной формы.Я прилагаю снимок экрана от JVisualVM, который показывает график распределения кучи в виде пилообразной формы.Программа представляет собой простой бесконечный цикл печати "Hello, World!"в консоль.

public class HelloWorld {
    public static void main(String a[]){
        while(true) {
            System.out.println("Hello, World!");
        }
    }
}

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

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

Ответы [ 4 ]

23 голосов
/ 29 августа 2011

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

Visual VM - Memory snapshot

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

Visual VM GC probes

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

6 голосов
/ 28 августа 2011

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

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

1 голос
/ 13 сентября 2012

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

Runtime.getRuntime().freeMemory() 

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

1 голос
/ 28 августа 2011

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

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

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

  • это служебная нагрузка в виртуальной машине NetBeans, где она заканчивается выводом

...