test repentina por perdida memoria llama jovenes estres enfermedad como ancianos java memory-leaks

repentina - La forma más fácil de causar pérdida de memoria en Java?



perdida de memoria repentina (9)

  1. Crear una colección de objetos en el alcance de la clase
  2. Periódicamente agregue nuevos objetos a la colección
  3. No deje caer la referencia a la instancia de la clase que contiene la colección

Como siempre hay una referencia a la colección y la instancia del objeto que posee la colección, el recolector de basura nunca limpiará esa memoria, lo que ocasionará una "fuga" con el tiempo.

Posible duplicado:
Creando una pérdida de memoria con Java

¿Cuál es la forma más fácil de causar una fuga de memoria Java?


"Una pérdida de memoria, en ciencias de la computación (o fugas, en este contexto), ocurre cuando un programa de computadora consume memoria pero no puede volver a liberarla al sistema operativo". (Wikipedia)

La respuesta fácil es: no puedes. Java hace gestión automática de memoria y liberará recursos que no son necesarios para usted. No puedes evitar que esto suceda. SIEMPRE podrá liberar los recursos. En los programas con gestión de memoria manual, esto es diferente. No puedes obtener algo de memoria en C usando malloc (). Para liberar la memoria, necesita el puntero que devuelve malloc y llamar a free () en él. Pero si ya no tiene el puntero (sobrescrito, o se excedió la vida útil), desafortunadamente no puede liberar esta memoria y, por lo tanto, tiene una pérdida de memoria.

Todas las otras respuestas hasta ahora están en mi definición, no son realmente pérdidas de memoria. Todos apuntan a llenar la memoria con cosas sin sentido muy rápido. Pero en cualquier momento, aún se podía desreferenciar los objetos que se crearon y liberar así la memoria -> SIN FUGAS. Sin embargo, la respuesta de acconrad es bastante aproximada, como tengo que admitir, ya que su solución es simplemente "bloquear" al recolector de basura al forzarlo en un bucle sin fin).

La respuesta larga es: puede obtener una pérdida de memoria escribiendo una biblioteca para Java utilizando el JNI, que puede tener administración de memoria manual y así tener pérdidas de memoria. Si llama a esta biblioteca, su proceso java perderá memoria. O bien, puede tener errores en la JVM, de modo que la JVM pierda memoria. Probablemente hay errores en la JVM, incluso puede haber algunos conocidos, ya que la recolección de basura no es tan trivial, pero sigue siendo un error. Por diseño esto no es posible. Es posible que solicite un código Java que se vea afectado por dicho error. Lo siento, no conozco uno y, de todos modos, podría no ser un error en la próxima versión de Java.


Aquí hay un ejemplo simple

public class finalizer { @Override protected void finalize() throws Throwable { while (true) { Thread.yield(); } } public static void main(String[] args) { while (true) { for (int i = 0; i < 100000; i++) { finalizer f = new finalizer(); } System.out.println("" + Runtime.getRuntime().freeMemory() + " bytes free!"); } } }


Parece que la mayoría de las respuestas no son fugas de memoria de estilo C.

Pensé que agregaría un ejemplo de una clase de biblioteca con un error que le dará una excepción de falta de memoria. De nuevo, no es una verdadera pérdida de memoria, pero es un ejemplo de algo que se está quedando sin memoria que usted no esperaría.

public class Scratch { public static void main(String[] args) throws Exception { long lastOut = System.currentTimeMillis(); File file = new File("deleteme.txt"); ObjectOutputStream out; try { out = new ObjectOutputStream( new FileOutputStream("deleteme.txt")); while (true) { out.writeUnshared(new LittleObject()); if ((System.currentTimeMillis() - lastOut) > 2000) { lastOut = System.currentTimeMillis(); System.out.println("Size " + file.length()); // out.reset(); } } } catch (Exception e) { e.printStackTrace(); } } } class LittleObject implements Serializable { int x = 0; }

Encontrarás el código original y la descripción del error en

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4363937


Por lo que he leído en la respuesta más votada, lo más probable es que esté pidiendo una fuga de memoria similar a C. Bueno, como hay colección de garbagge, no se puede asignar un objeto, perder todas sus referencias y conseguir que siga ocupando memoria, eso sería un serio error de JVM.

Por otro lado, puede suceder que filtre hilos, lo que, por supuesto, causaría este estado, porque tendría algún subproceso ejecutándose con sus referencias a objetos, y puede perder la referencia del subproceso. Aún puede obtener la referencia de subproceso a través de la API - http://www.exampledepot.com/egs/java.lang/ListThreads.html


Prueba esta clase simple:

public class Memory { private Map<String, List<Object>> dontGarbageMe = new HashMap<String, List<Object>>(); public Memory() { dontGarbageMe.put("map", new ArrayList<Object>()); } public void useMemInMB(long size) { System.out.println("Before=" + getFreeMemInMB() + " MB"); long before = getFreeMemInMB(); while ((before - getFreeMemInMB()) < size) { dontGarbageMe.get("map").add("aaaaaaaaaaaaaaaaaaaaaa"); } dontGarbageMe.put("map", null); System.out.println("After=" + getFreeMemInMB() + " MB"); } private long getFreeMemInMB() { return Runtime.getRuntime().freeMemory() / (1024 * 1024); } public static void main(String[] args) { Memory m = new Memory(); m.useMemInMB(15); // put here apropriate huge value } }


Realmente no se puede "perder memoria" en Java a menos que:

  • cadenas internas
  • generar clases
  • memoria de fuga en el código nativo llamado por jni
  • mantenga referencias a cosas que no desea en algún lugar olvidado u oscuro.

Supongo que estás interesado en el último caso. Los escenarios comunes son:

  • oyentes, especialmente hecho con clases internas
  • cachés

Un buen ejemplo sería:

  • crear una interfaz gráfica de Swing que inicie un número potencialmente ilimitado de ventanas modales;
  • hacer que la ventana modal haga algo como esto durante su inicialización:

    StaticGuiHelper.getMainApplicationFrame().getOneOfTheButtons().addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ // do nothing... } })

La acción registrada no hace nada, pero hará que la ventana modal permanezca en la memoria para siempre, incluso después del cierre, causando una fuga, ya que los oyentes nunca se anulan y cada objeto de clase interna anónimo contiene una referencia (invisible) a su objeto externo . Además, cualquier objeto al que se haga referencia desde las ventanas modales también tiene la posibilidad de tener una fuga.

Esta es la razón por la cual las bibliotecas como EventBus usan referencias débiles por defecto.

Además de los oyentes, otros ejemplos típicos son los cachés, pero no puedo pensar en un buen ejemplo.


public static List<byte[]> list = new ArrayList<byte[]>();

Y luego agregue arreglos (grandes) sin eliminarlos. En algún momento se le agotará la memoria sin sospechar. (Puede hacer esto con cualquier objeto, pero con arreglos grandes y completos puede agotar la memoria más rápidamente)

En Java, si desreferencia un objeto (se sale del alcance), se recoge basura. Entonces debe mantener una referencia para tener un problema de memoria.


La siguiente clase de Box extremadamente artificial perderá memoria si se usa. Los objetos que se put en esta clase son eventualmente (después de otra llamada para ser precisos ... siempre que el mismo objeto no sea insertado) inaccesibles para el mundo exterior. No se pueden desreferenciar a través de esta clase, sin embargo, esta clase garantiza que no puedan recopilarse. Esta es una fuga REAL. Sé que esto es realmente artificial, pero es posible hacer casos similares por accidente.

import java.util.ArrayList; import java.util.Collection; import java.util.Stack; public class Box <E> { private final Collection<Box<?>> createdBoxes = new ArrayList<Box<?>>(); private final Stack<E> stack = new Stack<E>(); public Box () { createdBoxes.add(this); } public void put (E e) { stack.push(e); } public E get () { if (stack.isEmpty()) { return null; } return stack.peek(); } }