2010-01-19 13 views

Respuesta

10

No, no lo garantiza. Es perfectamente posible que un programador cree erróneamente objetos que nunca salgan de su alcance, consumiendo más y más memoria hasta que todo el montón se agote.

Es responsabilidad del programador asegurarse de que los objetos que ya no se utilizan ya no se mencionen en la aplicación. De esta forma, el recolector de basura puede hacer su trabajo y recuperar la memoria utilizada por estos objetos.

Ejemplo

public class Main { 
    public static void main(String[] main) { 
    List<String> l = new LinkedList<String>(); 

    // Enter infinite loop which will add a String to 
    // the list: l on each iteration. 
    do { 
     l.add(new String("Hello, World")); 
    } while(true); 
    } 
} 
+0

podría hacer que la memoria sangrara mucho más rápido si hiciera la cadena más grande :) – medopal

+0

De hecho ... aunque explícitamente he llamado "nuevo" para evitar hacer referencia al mismo literal de cadena. – Adamski

2

No. Si se construye una gran cantidad de objetos (millones) y mantener una referencia a ellos para que no se vayan fuera de alcance (por ejemplo, mediante su inclusión en un ArrayList), podría quedarse sin memoria direccionable.

4

No, todavía hay muchas formas de quedarse sin memoria. El recolector de basura solo puede reclamar memoria para los objetos a los que ya no se hace referencia. Depende de usted asegurarse de que no está haciendo referencia a objetos que no necesita, o de usar referencias suaves para los objetos que le gustaría tener, pero no los use. No me importa desaparecer si la memoria se agota.

22

No, siempre es posible que intente asignar más memoria de la disponible.

La recolección automática de basura solo significa que la basura (es decir, la memoria sin referencia) se recoge automáticamente (es decir, reclamada para un uso posterior). Si conserva referencias, no es basura ni recopilada.

1

Absolutamente no. Incluso en un lenguaje recolectado como basura, puede perder fácilmente referencias, lo que significa que los objetos nunca recibirán basura.

Incluso entonces, simplemente puede instanciar (y mantener la referencia) demasiados objetos para que el sistema los maneje.

1

¿Cómo podría algo garantizar que un programa no se quede sin memoria, salvo que se elimine arbitrariamente un elemento de la memoria para dejar espacio para nuevas asignaciones?

Ahora, ¿qué pasa si realmente mantiene una referencia sobre (usar) la cosa elegida al azar para ser desalojada? Pronto tendrá un comportamiento incorrecto.

0

No. La recolección de basura solo protege contra un tipo de pérdida de memoria. Específicamente, del tipo que ocurre si no liberas memoria explícitamente cuando tu aplicación ya no la necesita. Si su aplicación contiene referencias a objetos innecesarios (p. Ej., Listas siempre en crecimiento), el recolector de basura no puede limpiarlos y su aplicación aún puede quedarse sin memoria.

0

No, en absoluto.

En idiomas sin recolección de basura, el programador (o la biblioteca que usa) es responsable de realizar solicitudes de memoria y devolver la memoria asignada para "reciclar". no hay garantías de que la memoria esté disponible cuando se solicite. Sin embargo, si nunca "recicla" explícitamente, podría haber una situación en la que se rechazó una solicitud porque no hay memoria disponible, pero si la memoria se recicló, ese bloque podría haberse devuelto para esta solicitud.

Tener una recolección de basura automatizada significa que el sistema puede reciclar para usted. Como resultado, ciertas solicitudes se llenarían con la memoria "reciclada". Sin embargo, al igual que con los idiomas que no son GC, algunas solicitudes no se pueden completar.

Por ejemplo, si su sistema tiene 1000 bloques disponibles y necesita 1500 al mismo tiempo, ningún GC en el mundo lo ayudará porque no hay nada realmente disponible para reciclar.

0

No, la recolección de basura no puede garantizar que su aplicación no se quede sin memoria. Ni siquiera garantizará que su aplicación no se quede sin memoria cuando la memoria esté disponible. Si está a punto de quedarse sin memoria o está asignando muchos objetos, puede provocar que GC rompa, generando una excepción de falta de memoria. El programa también puede quedarse sin memoria cuando ha utilizado toda la memoria física (real y virtual) o el programa excede la memoria máxima permitida por la JVM (consulte -Xmx).

0

No. El recolector de basura, le ayuda a liberar la memoria no utilizada automáticamente.

La forma en que funciona es, si no se puede acceder a una referencia de objeto, la memoria de ese objeto puede ser basura.

Por ejemplo:

public void test() { 
    Object o = new Object(); 
    // the memory used by o may be garbage collected after this line 
} 

Pero si nunca suelte referencias a objetos, el recolector de basura nunca va a cobrar nada y una OutOfMemoryError será lanzado.

List list = .... 
public void test() { 
    o = new Object(); 
    list.add(o); 
    // the memory used by o WON'T be garbage collected after this line 
    // because its reference is used in the list. 
} 

Si utiliza varias veces:

while(true) { 
    test(); 
} 

La lista seguirá creciendo de forma indefinida hasta que se agote la memoria

3

Para responder a su pregunta, NO. La recolección de basura no garantiza que un programa no se quede sin memoria.

  • Considere el objeto que no quiere usar más son como basura.
  • Las referencias a esos objetos serán como tener esa basura en su casa .
  • La recolección de basura es como el camión de basura de la ciudad que recoge basura.
  • Si no va a liberar esas referencias , es como no tomar basura y pronto su casa va a ser más de lleno de basura como tipos de camiones de basura no se llevará a cabo la basura de su casa.

El recolector de basura recogerá los objetos no referenciados automáticamente. En Java, la mayoría de las referencias a objetos se liberan automáticamente una vez que sales del método.

Los objetos tienen referencia a otros objetos, que a su vez se refieren a otros objetos que crean un gráfico de objeto completo. Entonces, como dicho objeto puede ser referenciado por más de un objeto.

  • Si el objeto es tener cero referencias, es elegible para la basura colección.
  • Los objetos se asignan en el montón.
  • El recolector de basura se ejecuta de tiempo a tiempo para eliminar los objetos sin referencia del montón.
  • Si se mantiene la creación de más objetos de montón sin soltar va finalmente obtener OutOfMemoryError

Ejemplo con la recolección de basura en el trabajo

public class TestGarbageNoError { 

public static void main(String[] args) { 
    String hugeString; 
    for (int i = 0; i < Integer.MAX_VALUE; i++) { 
    System.out.println("i = " + i); 
    hugeString = getHugeString(); 
    // At each iteration reference variable hugeString 
    // points to new String object. Hence there will be 
    // zero reference to previous string object and will 
    // eventually be garbage collected 
    } 
} 

public static String getHugeString() { 
    StringBuilder sb = new StringBuilder(); 
    for (int x = 0; x < 5000000; x++) { 
    sb.append(x); 
    } 
    return sb.toString(); 
} 
} 

.

Ejemplo con pérdida de memoria en el trabajo

public class TestGarbageError { 

public static void main(String[] args) { 
    Collection<String> memoryLeak = new ArrayList<String>(); 
    for (int i = 0; i < Integer.MAX_VALUE; i++) { 
    System.out.println("i = " + i); 
    String hugeString = getHugeString(); 
    memoryLeak.add(hugeString); 
    // At each iteration reference variable hugeString 
    // points to new String object. But all objects are added 
    // to memoryLeak Collection and will always have atleast one 
    // reference, i.e. from memoryLeak object. Hence this string 
    // objects will never be garbage collected and program will 
    // eventually run out of memory 
    } 
} 

public static String getHugeString() { 
    StringBuilder sb = new StringBuilder(); 
    for (int x = 0; x < 5000000; x++) { 
    sb.append(x); 
    } 
    return sb.toString(); 
} 
} 
+0

no lo entiendo, en el segundo ejemplo String se define dentro de for loop, por lo que con cada iteración el puntero se pierde en la pila, probablemente sobreescrito con uno nuevo (la forma de ver cómo van las cosas). Explique qué ocurre en cada iteración con este objeto String .... –

+0

Ha faltado la línea "memoryLeak.add (hugeString);". Aquí es donde se mantiene la referencia a cada cadena debido a que se ha filtrado la memoria. Intenta ejecutar ambos programas, verás la diferencia en los resultados. –

+0

ahh ... sí, ahora vi esa línea adicional. Por supuesto, ¿qué pasa si en algún lugar es el código memoryLeak.get (...), el objeto debe mantener la referencia a String. Pensé que había algo con lugar de definición donde se coloca String hugeString ... –

0

Sin embargo, se garantiza que antes de la JVM declara OutOfMemoryException va a recoger la basura todas las referencias de colección y considerar utilizar la memoria ahora libre.

Cuestiones relacionadas