Почему график пилообразной формы?
когда я запускаю приведенный ниже код с помощью NetBeans, график размера выделенной кучи напоминает пилообразную форму. Я прикрепляю захват экрана из JVisualVM, который показывает график распределения кучи с пилообразной формой. Программа представляет собой простой бесконечный цикл печати " Hello, World!"в консоль.
public class HelloWorld {
public static void main(String a[]){
while(true) {
System.out.println("Hello, World!");
}
}
}
Может ли кто-нибудь объяснить причину формы графика используемой кучи?
PS: это происходит даже если я запускаю его без использования NetBeans, поэтому он, скорее всего, не связан с NetBeans...
4 ответов
пилообразный шаблон в использовании кучи можно объяснить тем, что во время вызова System.out.println
ссылка. Особенно в Oracle / Sun JRE, несколько HeapCharBuffer
экземпляры создаются в молодом поколении, как отмечено в следующем снимке, полученном с помощью профилировщика памяти VisualVM:
интересный бит в числа живых объектов, которые присутствуют в куче. Образец пилообразной результаты цикла сбора мусора young-gen, который происходит, когда пространство eden заполняется; поскольку в программе нет тяжелой вычислительной активности, JVM может выполнить несколько итераций цикла, в результате чего пространство eden (размером 4 МБ) заполняется. Следующий цикл сбора молодого поколения затем очищает большую часть мусора; это почти всегда все пространство Эдема, если объекты все еще используются, как указано в следующем полученном следе gc из который VisualVM:
любой процесс выделения объектов с регулярной скоростью приведет к устойчивому увеличению потребления памяти кучи, а затем мгновенные падения, когда сборщик мусора собирает больше не используемые объекты, что приводит к этой пилообразной форме.
в случае, если вы задаетесь вопросом, почему ваш процесс java сохраняет память распределения при записи в System.out
, имейте в виду, что другие потоки (например, тот, который подает текущую статистику памяти в JVisualVM) могут быть теми, которые выделяют память.
есть много мест, откуда это может исходить, и это, вероятно, зависит от реализации. По крайней мере, возможно следующее (Но все это только предположения)
где-то в стеке потоков под системой.из.println существует выделение массива байтов (учитывая, что одним из основных методов выходного потока является write(bytes []b, int off, int len))
это накладные расходы, используемые программным обеспечением мониторинга, которое вы используете (я не использовал его)
это накладные расходы в NetBeans VM, где он в конечном итоге показывает вывод
фактически jVisualVM вызывает дополнительное выделение объекта. Jvisualvm и jconsole используют расширения управления Java. Присоединение к запущенному приложению и запрос метрик JVM, вызывающих создание дополнительных объектов. Вы можете проверить это, добавив в свою программу вызов
Runtime.getRuntime().freeMemory()
который сообщает о свободной памяти в куче JVM. Он покажет [почти] без изменения памяти, запустив ваш код, но как только вы подключите jVisualVM к своей программе, вы увидите использование памяти увеличение.