¿Por qué un gráfico en forma de diente de sierra?

Cuando ejecuto el código mencionado a continuación usando NetBeans, el gráfico del tamaño del montón asignado se asemeja a una forma de diente de sierra. Adjunto la captura de pantalla de JVisualVM, que muestra el gráfico de asignación de montón con una forma de diente de sierra. El progtwig es una simple impresión de bucle infinito “Hello, World!” en la consola.

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

enter image description here ¿Alguien puede explicar la razón detrás de la forma del gráfico del montón usado?

PD : Esto sucede incluso si lo ejecuto sin utilizar NetBeans, por lo que lo más probable es que no esté relacionado con NetBeans …

El patrón de diente de sierra en el uso del montón se puede explicar por el hecho de que se crean varias variables locales durante la invocación de System.out.println . Principalmente en Oracle / Sun JRE, varias instancias de HeapCharBuffer se crean en la generación joven, como se observa en la siguiente instantánea obtenida usando el perfilador de memoria de VisualVM:

Visual VM - Instantánea de memoria

El bit interesante está en la cantidad de objetos en vivo que están presentes en el montón. El patrón de dientes de sierra es el resultado del ciclo de recolección de basura de jóvenes que ocurre cuando el espacio de eden se llena; dado que no se realiza una gran actividad de cómputo en el progtwig, la JVM puede ejecutar varias iteraciones del ciclo, lo que da como resultado que se llene el espacio de eden (de 4 MB de tamaño). El siguiente ciclo de recolección de jóvenes genera la mayor parte de la basura; casi siempre es todo el espacio de eden, a menos que los objetos estén todavía en uso, como lo indica la siguiente traza de gc obtenida de VisualVM:

Sondas Visual VM GC

El comportamiento del patrón de diente de sierra se puede explicar así mediante una serie de asignaciones de objetos en rápida sucesión que llenan el espacio de eden, lo que desencadena un ciclo de recolección de basura joven gen; este proceso se repite cíclicamente sin demoras, ya que el proceso JVM subyacente no es reemplazado por otro proceso, y el subproceso principal dentro de la JVM que es responsable de las asignaciones de objetos tampoco es reemplazado por otro subproceso.

Cualquier proceso que asigne objetos a una velocidad normal dará como resultado un aumento constante en el consumo de la memoria de stack, seguido de caídas instantáneas cuando el recolector de basura recolecte los objetos que ya no se usan, lo que da como resultado la forma de diente de sierra.

En caso de que se pregunte por qué su proceso java guarda la memoria de asignación al escribir en System.out , tenga en cuenta que otros hilos (por ejemplo, el que alimenta las estadísticas actuales de la memoria a JVisualVM) pueden ser los que asignan la memoria.

Hay muchos lugares de donde podría venir, y es probable que dependa de la implementación. Al menos los siguientes son posibles (pero todos son meramente especulativos)

  • en algún lugar de la stack de flujos debajo de System.out.println hay una asignación de matriz de bytes (dado que uno de los métodos básicos de una secuencia de salida es escribir (bytes [] b, int off, int len))

  • es sobrecarga utilizada por el software de monitoreo que está utilizando (no lo he usado)

  • está sobrecargado en la máquina virtual Netbeans donde termina mostrando la salida

En realidad, jVisualVM causa la asignación de objetos adicionales. jVisualVM y jconsole están utilizando Java Management Extensions. Adjuntar a la aplicación en ejecución y solicitar métricas de JVM que causen que se creen objetos adicionales. Puede verificar esto agregando a su progtwig llamada a

 Runtime.getRuntime().freeMemory() 

que informa la memoria libre en el montón de JVM. Mostrará [casi] ningún cambio de memoria ejecutando su código, pero tan pronto como conecte jVisualVM a su progtwig verá un aumento en el uso de la memoria.