2011-08-28 69 views
17

Cuando ejecuto el código mencionado más abajo (usando netbeans), el tamaño del montón asignado varía en una forma de diente de sierra. Adjunto la captura de jVisualVM que muestra el gráfico de montón usado en forma de diente de sierra. El programa es una simple impresión de ciclo infinito "lol" n el stdout.¿Por qué un gráfico en forma de diente de sierra?

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

enter image description here ¿Puede alguien explicar la razón de la forma del gráfico del montón usado?

ps: Esto sucede incluso si lo ejecuto sin utilizar NetBeans por lo tanto no está relacionada con NetBeans ...

+1

Y parece variar en un buen ... uh ... ¿3 megabytes? Puede eso ser verdad? – Owen

+0

Obtendrá una idea de esto al probar otros algoritmos de recolector de elementos no utilizados. Consulte aquí para obtener información: http://www.tikalk.com/java/garbage-collection-serial-vs-parallel-vs-concurrent-mark-sweep – skaffman

+3

@ buch11: nunca subestime la gigantesca cantidad de basura, incluso la Java más trivial método/API es capaz de generar. He hecho cálculos científicos con múltiples subprocesos usando Java y puedo decirte que hay tantos errores que ni siquiera son graciosos;) Debes darte cuenta de que la mayoría de los programadores Java usarán cosas como * Map * y te contarán que si no es un cuello de botella no tiene nada de malo. Java es básicamente un mundo en el que casi todo el mundo genera incontables desechos y piensa: * "El recolector de basura se encargará de eso" *. Hay una razón por la cual Photoshop no está escrito en Java;) – SyntaxT3rr0r

Respuesta

23

El patrón de diente de sierra en el uso de montón se puede explicar por el hecho de que se crean varias variables locales durante la invocación de la invocación System.out.println. Lo más notable en el Oracle/Sun JRE, varios HeapCharBuffer casos se crean en la generación joven, como se indica en la siguiente instantánea obtenida utilizando el generador de perfiles de memoria de VisualVM:

Visual VM - Memory snapshot

La parte interesante es en el número 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 programa, 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; es casi siempre la totalidad del espacio eden, a menos que los objetos son todavía en uso, como se indica por la siguiente traza gc obtenida de VisualVM:

Visual VM GC probes

El comportamiento del patrón de diente de sierra de este modo se puede explicar por una serie de asignaciones de objetos en rápida sucesión que llenan el espacio de eden, desencadenando un ciclo de recolección de basura de gen jóvenes; 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.

+0

¡Ya entendí! Gracias. – buch11

+0

De nada. Por cierto, no obtuve ondas de diente de sierra perfectas, ya que mantuve Alt-tabbing entre VisualVM y Eclipse. Por otro lado, su captura de pantalla indica que ha estado ejecutando VisualVM durante bastante tiempo. –

+0

en realidad estaba programando algo que hace uso de hilos, de repente el código entró en infinito loo, fui a JVisualVM para verificar cuál de los hilos estaba funcionando/durmiendo/esperando., Y el diente de sierra se colocó frente a mí, a la vez pensé que era algo relacionado con los hilos, pero luego intenté ejecutar el código de arriba y todos los acertijos comenzaron a partir de allí ... así que mi VisualVM se estaba ejecutando todo el tiempo. – buch11

1

hay un montón de lugares que puede provenir de, y lo más probable es dependiente de la implementación. Al menos los siguientes son posibles (pero son todas especulaciones)

  • en algún lugar de la pila de corrientes por debajo System.out.println hay una asignación de matriz de bytes (dado que uno de los métodos básicos de un flujo de salida es de escritura (bytes [] b, int off, int len))

  • que es utilizada por el propio software de monitorización que está usando (no he usado)

  • es sobrecarga en los netbeans VM donde termina mostrando la salida

5

Cualquier proceso de asignación de objetos a ritmo normal dará como resultado un aumento constante en el consumo de memoria de pila, seguido de caídas instantáneas cuando el recolector recoge 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 mientras escribe en System.out, tenga en cuenta que otros hilos (por ejemplo, el que alimenta las estadísticas de memoria actuales a JVisualVM) pueden ser los que asignan la memoria.

1

En realidad, jVisualVM provoca 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. Esto se puede comprobar mediante la adición a su llamada programa para

Runtime.getRuntime().freeMemory() 

que informa de 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 programa verá un aumento en el uso de la memoria.

Cuestiones relacionadas