Me hacen esta pregunta muchas veces. ¿Cuál es una buena manera de responder?Puede haber pérdida de memoria en Java
EDIT: Gracias a todos por todas las respuestas.
Me hacen esta pregunta muchas veces. ¿Cuál es una buena manera de responder?Puede haber pérdida de memoria en Java
EDIT: Gracias a todos por todas las respuestas.
Can there be memory leak in Java?
La respuesta es que Depende del tipo de pérdida de memoria de la que estés hablando t.
Las pérdidas de memoria de C/C++ clásicas se producen cuando una aplicación omite free
o dispose
un objeto cuando han terminado con él, y tiene fugas. Las referencias cíclicas son un sub-caso de esto donde la aplicación tiene dificultades para saber cuándo free
/dispose
, y deja de hacerlo como resultado. Los problemas relacionados se producen cuando la aplicación utiliza un objeto después de que se ha liberado o intenta liberarlo dos veces. (Se podría llamar los últimos problemas de pérdidas de memoria, o sólo errores. De cualquier manera ...)
Java y lenguajes su mayoría no sufren de estos problemas otra (totalmente) gestionado debido a que el GC se encarga de liberar objetos que ya no son alcanzables. (Ciertamente, el puntero colgante y los problemas de doble liberación no existen, y los ciclos no son problemáticos, como lo son para los "indicadores inteligentes" de C/C++ y otros esquemas de recuento de referencias).
Pero en algunos casos, GC en Java pierda objetos que (desde la perspectiva del programador) deberían ser recolectados. Esto sucede cuando el GC no puede descubrir que un objeto no puede ser alcanzado:
(Tenga en cuenta que las causas de las pérdidas de memoria en Java pueden ser simples o muy sutiles;. Véase la respuesta de @ jonathan.cone para algunas sutiles El último que potencialmente implica recursos externos que no debería confía en el GC para tratar de todos modos.)
De cualquier forma, puede tener una situación en la que los objetos no deseados no puedan ser recolectados, y evitar la acumulación de memoria ... una pérdida de memoria.
Luego está el problema de que una aplicación o biblioteca Java puede asignar objetos fuera de pila a través de código nativo que necesita ser administrado manualmente. Si la aplicación/biblioteca tiene errores o se usa incorrectamente, puede obtener una pérdida de memoria nativa. (Por ejemplo: Android Bitmap memory leak ... señalando que se solucione este problema en versiones posteriores de Android.)
1 - Estoy aludiendo a un par de cosas. Algunos idiomas administrados le permiten escribir código no administrado en el que puede crear fugas clásicas de almacenamiento. Algunos otros lenguajes administrados (o más concretamente implementaciones de lenguaje) usan recuento de referencias en lugar de recolección de basura adecuada.Un administrador de almacenamiento basado en el recuento de referencias necesita algo (es decir, la aplicación) para interrumpir los ciclos ... de lo contrario, se producirán fugas de almacenamiento.
+1 para los detalles. – fastcodejava
sí, si no quita la referencia a los objetos, nunca se recolectarán basura y aumentará el uso de la memoria. sin embargo, debido a la forma en que está diseñado java, esto es difícil de lograr, mientras que en otros idiomas esto a veces es difícil de lograr.
editar: leer el enlace de Amokrane. es bueno.
Si no está haciendo referencia al objeto, puede ser GC'd. Si estás (y no en un circuito cerrado), entonces no es una "fuga". Ipso, facto. –
@ T.J. Crowder: Esa es una muy ... estricta interpretación de "fuga". Y no es muy útil, en eso. Supongamos que alguna clase mantiene un caché interno de varios objetos, pero sigue volviendo a agregar nuevas instancias a ese caché en lugar de volver a utilizarlas. El uso de la memoria sigue aumentando y el montón está lleno de objetos que nunca volverán a usarse, y eso a mí me parece una "fuga de memoria". –
@Anon: en su mayor parte era frívola. Pero su punto es realmente una buena * respuesta *, sugiero agregarlo como uno solo. –
La respuesta corta:
A competent JVM has no memory leaks, but more memory can be used than is needed, because not all unused objects have been garbage collected, yet. Also, Java apps themselves can hold references to objects they no longer need and this can result in a memory leak.
Una respuesta aún más corto:
Java is a language and can't have memory leaks, only Java Virtual Machines can.
No creo que esto sea útil. El hecho es que las ** aplicaciones ** de Java pueden, y a menudo tienen, pérdidas de memoria. –
@Stephen, gracias, he actualizado mi respuesta para que sea menos ambigua. –
¿Cómo pueden las JVM tener pérdidas de memoria cuando no son las que tienen la memoria? – Pacerier
Sí, es posible.
En Java efectivo hay un ejemplo que involucra una pila implementada usando matrices. Si sus operaciones pop simplemente disminuyen el valor del índice, es posible tener una pérdida de memoria. ¿Por qué? Debido a que su matriz todavía tiene una referencia al valor reventado y todavía tiene una referencia al objeto de la pila. Entonces, lo correcto para esta implementación de pila sería borrar la referencia al valor reventado utilizando una asignación nula explícita en el índice de matriz reventado.
Sí, en el sentido de que su aplicación Java puede acumular memoria a lo largo del tiempo que el recolector de basura no puede liberar.
Al mantener las referencias a los objetos no deseados/no deseados, nunca se saldrán del alcance y su memoria no volverá a reclamarse.
Sí. Las fugas de memoria aún pueden ocurrir incluso cuando tiene un GC. Por ejemplo, puede conservar recursos como los conjuntos de resultados de la base de datos que debe cerrar manualmente.
Una respuesta simple es: JVM se encargará de toda tu inicialización de POJO [objetos antiguos de java] siempre que no estés trabajando con JNI. Con JNI, si ha realizado alguna asignación de memoria con el código nativo, debe ocuparse de esa memoria usted mismo.
Bueno, teniendo en cuenta que java utiliza un recolector de basura para recoger objetos no utilizados, no puede tener un puntero colgando. Sin embargo, puede mantener un objeto en el alcance durante más tiempo de lo necesario, lo que podría considerarse una pérdida de memoria. Más sobre esto aquí: http://web.archive.org/web/20120722095536/http://www.ibm.com:80/developerworks/rational/library/05/0816_GuptaPalanki/
¿Estás tomando una prueba sobre esto o algo así? Porque eso es al menos un A + justo allí.
Respuesta agradable y simple. – vz0
su enlace no funciona y está roto –
La respuesta es un rotundo sí , pero esto es generalmente un resultado del modelo de programación más que una indicación de algún defecto en la JVM. Esto es común cuando los marcos tienen ciclos de vida diferentes de eso que una JVM en ejecución.Algunos ejemplos son:
* - Los mil millones de dólares de consultoría se han hecho para resolver el último
Sí. Una pérdida de memoria es una memoria no utilizada que la aplicación no ha liberado al administrador de memoria.
que he visto muchas veces Java almacena código wich elementos en una estructura de datos, pero los artículos nunca se retiran de allí, llenando la memoria hasta un OutOfMemoryError:
void f() {
List<Integer> w = new ArrayList<Integer>();
while (true) {
w.add(new Integer(42));
}
}
Aunque este ejemplo es demasiado obvio, Java los errores de memoria tienden a ser más sutiles. Por ejemplo, usando Dependency Injection almacenando un objeto enorme en un component with SESSION
scope, sin soltarlo cuando el objeto ya no se usa.
En una VM de 64 bits, esto tiende a empeorar ya que el espacio de memoria de intercambio comienza a llenarse hasta que el sistema rastrea en demasiadas operaciones de IO.
Esto no es una pérdida de memoria, es solo una programación deficiente. Todos estos objetos todavía se pueden referenciar para que no se "filtren" – ed209
El libro Effective Java da dos razones más para "pérdidas de memoria":
recurso muy detallado aquí: http://www.ibm.com/developerworks/library/j-leaks/ –
Esta pregunta se ha hecho tantas veces como usted sugiere, y de hecho tiene muchas respuestas en este foro ya . –
Buena pregunta. Aprendí muchas cosas de las respuestas. – fastcodejava