2011-12-02 23 views
23

Estoy explorando el uso de la memoria en Java para entender por qué mi programa pierde memoria. Después de quitar el código en mi ciclo while principal, todavía tengo un aumento en el uso de la memoria a lo largo del tiempo. Reflexionando sobre el uso de memoria de un programa vacío:¿Por qué un programa Java vacío consume memoria?

class Nothing 
{ public static void main(String[] args) 
    { while(true); } 
} 

Todavía se registró un aumento de la memoria:

Image description here

Así que mi pregunta es: ¿Por qué hay todavía un patrón de diente de sierra? ¿Por qué cuando se ejecuta el GC no guarda toda la memoria (cada vez que se ejecuta el gc (los valles) la memoria utilizada aumenta en 10-20 Kb (en comparación con el valle anterior))?

EDIT:

java version "1.6.0_29"

Java (TM) SE Runtime Environment (build 1.6.0_29-b11)

Java HotSpot (TM) VM cliente (construir 20.4-b02, mixed mode, sharing)

SO: Windows 7 Enterprise-32 bits

+0

No veo un aumento. La memoria sube, luego se acumula.Parece que la memoria máxima utilizada es constante a lo largo del tiempo. –

+0

Otra herramienta para buscar la pérdida de memoria en su aplicación es [Plumbr] (http://plumbr.eu). Debería ser mucho más fácil que luchar con los perfiladores e intentar deducir algo de toda esa información. – Nikem

Respuesta

10

¿Por qué todavía hay un patrón de diente de sierra?

Si no me equivoco, parte de la razón es que el monitor está forzando a la aplicación a crear objetos temporales que contienen información sobre el estado de la recolección de basura y el uso de memoria.

¿Por qué cuando se ejecuta el GC no se guarda toda la memoria (cada vez que se ejecuta el gc (los valles) la memoria utilizada aumenta en 10-20Kb (en comparación con el valle anterior))?

Creo que el monitor no ve instantáneamente la cantidad de memoria utilizada después de la recolección de basura, sino que debe sondear con frecuencia para ver el uso de la memoria. Por lo tanto, el "valle" percibido es necesariamente algo más alto que el valle verdadero. Me gustaría suponer que el aumento percibido en el uso de memoria en los valles es solo un artefacto aleatorio de esta discrepancia, y se neutralizaría con el tiempo. (Es decir, no creo que en realidad haya entre 10 y 20 KB de pérdida de memoria en cada ciclo).

+0

Entonces, ¿cómo podría obtener una imagen más precisa de lo que sucede debajo del capó? – GoldfishGrenade

+0

¿En un programa real, o en su programa de prueba no-while-while-loop? En un programa real, un montón de archivos te ayudará a descubrir qué tipo de objeto no se recogerá, lo que puede ayudarte a descubrir qué parte de tu programa podría ser el culpable. – ruakh

+0

+1 Esto es absolutamente causado por los beans de administración y cualquier protocolo utilizado para hablar con ellos (probablemente RMI ya que es el predeterminado). – Fredrik

4

Esto es un artefacto del generador de perfiles, sin el generador de perfiles no habrá asignaciones. Los diferentes perfiladores producen diferentes artefactos, dependiendo de cómo registran los datos. Abajo se puede ver lo que los perfiles Nothing JProfiler se verá así:

enter image description here

Mucho menos de un patrón de diente de sierra. Sin embargo, también hay un consumo de memoria minúscula:

enter image description here

que es debido al hecho de las encuestas de perfiles de agente del grano java.lang.management.MemoryUsage JMX. Eventualmente, este consumo también desencadenará una recolección de basura.

Cuestiones relacionadas