usage not leak how exist example debug java api memory-leaks

not - Fugas de memoria en la API estándar de Java



memory leak example in java (6)

Cada creación de instancias de un subproceso asigna memoria para una pila (por defecto 512k, sintonizable vía -Xss ). No se trata de una fuga como tal , pero un intento ingenuo de aplicar múltiples hilos en una aplicación resultará en un considerable consumo no obvio de memoria.

¿Qué clases de la API estándar de Java pueden causar pérdidas de memoria cuando se usan de una manera (no obviamente) incorrecta? ¿Y cómo se pueden evitar / corregir estas pérdidas de memoria?

Ejemplo: ObjectInputStream y ObjectOutputStream mantienen referencias a todos los objetos que han visto para poder enviar sucesos subsiguientes del mismo objeto como referencias en lugar de copias (y por lo tanto se ocupan de referencias circulares). Esto provoca una pérdida de memoria cuando mantiene dicha secuencia abierta indefinidamente (por ejemplo, cuando la usa para comunicarse a través de la red).

Solución: restablecimiento de llamada () periódicamente o después de cada objeto de nivel superior.


Cualquier clase con el método dispose ()

Por ejemplo java.awt.Window#dispose :

disposición pública de vacío ()

Libera todos los recursos de pantalla nativos utilizados por esta ventana, sus subcomponentes y todos sus hijos propios. Es decir, los recursos para estos componentes se destruirán, cualquier memoria que consuman se devolverá al sistema operativo y se marcarán como no reproducibles.


Cualquier clase interna no estática que hagas se aferre a las clases externas. Para que esa clase interna de aspecto inocente pueda aferrarse a un gran gráfico de objetos. Coloque la instancia en una colección estática o de toda la aplicación en algún lugar y está usando mucha memoria que no debería usar.


Todo lo que registra como destinatario de un evento, por ejemplo, en marcos de GUI, no se puede recolectar como basura siempre que esté registrado y el origen del evento esté activo.

Esto puede introducir pérdidas de memoria, si un desarrollador no tiene conocimiento de esa referencia fuerte del origen del evento al suscriptor del evento.


Una gran cosa es que obtener subcadenas de cadenas de Java se refiere a la cadena original.

Ejemplo: lee en un registro de 3000 caracteres y obtiene una subcadena de 12 caracteres, devolviéndola a la persona que llama (dentro de la misma JVM). Aunque no tenga una referencia directa a la cadena original, esa cadena de 12 caracteres aún usa 3000 caracteres en la memoria.

Para los sistemas que reciben y luego analizan muchos mensajes, esto puede ser un problema real.

Tienes un par de maneras de evitar esto:

String sub = new String(str.substring(6,12));

o

String sub = str.substring(6,12).intern();

El primero es más claro. El segundo tiene otras implicaciones porque estás usando el espacio PermGen. Si se usa demasiado, puede agotarse a menos que le dé suficiente a su máquina virtual.

Recuerda que esto solo es relevante si tomas subcadenas pequeñas y luego descartas la secuencia original y estás haciendo esto mucho.


Uso de referencias fuertes cuando las referencias débiles hubieran sido suficientes. La aplicación y las API que realizan su propia administración de recursos y estado son los culpables habituales aquí.

Luego, está el uso del patrón Observer, que podría provocar pérdidas de memoria: cuando el observador se desmarca del sujeto, la memoria no puede recuperarse a menos que el sujeto también libere la referencia al observador / oyente. Esto ya se ha señalado anteriormente, pero no muchas personas se dan cuenta de que incluso los madereros son observadores.

Además, existe la posibilidad de clases, cuyos objetos cuando se crean instancias se colocan automáticamente en un miembro estático . Algunas de estas clases ni siquiera tienen un método de liberación () o un método de eliminación () para que el miembro estático mantenga las referencias. Esta variedad de pérdidas de memoria finalmente produce un error OutOfMemory con un problema de espacio PermGen informado como la causa raíz, por lo que es más difícil de diagnosticar.