2012-07-10 32 views
7

Bueno, he desarrollado una aplicación Java que usa varias relaciones de objetos que hacen que el uso de la memoria sea demasiado caro. No tengo experiencia en la administración de la memoria Java porque el diseño de la aplicación dificulta la destrucción de objetos y la utilización del espacio previamente borrado. Por ejemplo, estoy usando Observer y patrones MVC.Cómo destruir objetos Java?

Por lo tanto, la teoría dice que ..

Un objeto se puede elegir para la recolección de basura o GC si no es accesible desde cualquier hilo en vivo o cualquier referencia estática

En otras palabras, puede decir que un objeto se vuelve elegible para la recolección de basura si todas sus referencias son nulas.

Pero, en mi corta experiencia, me resulta demasiado difícil destruir todas las referencias de objetos que quiero eliminar de la memoria (por ejemplo, cuando un marco está cerrado) cuando tiene un escenario como el mío, donde se pone No sé cuántas referencias existen en sus clases.

De acuerdo con este contexto, ¿cómo puedo tratar la destrucción de objetos cuando hay múltiples referencias a ella? o ¿cómo necesito administrar la memoria cuando tienes referencias complejas entre sí?

Respuesta

17

llevar un registro

Según este contexto, ¿cómo puedo hacer frente a la destrucción de objetos cuando hay múltiples referencias a ella?

Asegurándose de que estas referencias ya no sean necesarias.

Si les aísla, incluso en un gráfico aislado grande de objetos no utilizados que no están conectados ya a su progama principal, , todos ellos tienen derecho a la recolección de basura.

Las variables locales que han llegado al final de su alcance serán elegibles para objetos de recolección de basura (y sus contenidos), si no se han "vinculado" a nada (agregado a una colección, ac ompuesto, etc. ...). Para objetos UI, que de hecho pueden ser difíciles de razonar en términos de gráficos de objetos, asegúrese de desecharlos correctamente o de leer la documentación para asegurarse de que se eliminen de forma natural.

Simplified View of Reference Counting in the JVM

"Deja [GC] solo !!"

o ¿cómo necesito administrar la memoria cuando tiene referencias complejas entre sí?

No puede "administrar" la memoria. Simplemente puede administrar referencias. La idea es "severas" sus conexiones con sus objetos simplemente sin tener referencias a ellos. Luego viven en la memoria hasta que el CG los extermine.

No intente meterse con el GC para obligarlo a hacer cosas.Es una bestia bastante inteligente, y si bien se puede tratar para instruir a reaccionar ante algunas peticiones explícitamente - puede ignorar que - es usually a bad idea: do not invoke the GC explicitly, evitar finalizadores y explicit nullingif you don't understand their implications.


Nota para responder a su comentario

Simplemente anulación una referencia a un objeto que se ha agregado a varias colecciones o compuestos no hará que sea elegible para la colección. Al hacer esto, you'd have only nulled one reference.

Necesita eliminar este objeto de todas las listas o contenedores que tienen una referencia (básicamente, haciendo que "olviden" este objeto). Una vez que ningún objeto todavía "recuerda" o tiene un "enlace" a su objeto creado, se convierte en un elemento solitario en el gráfico del recolector de basura, lo que lo convierte en candidato para su eliminación.

Tal vez suene tedioso, pero si lo considera desde un lenguaje donde gestiona manualmente la memoria (C o C++, para nombrar las 2 referencias obvias), liberando y anulando punteros a los objetos dinámicamente asignados de hecho los destruiría, pero igual tendría que eliminar el elemento de las listas (o de cualquier contenedor) o parecerían depósitos vacíos a un puntero nulo.


Lectura adicional

+0

¡Entendido! pero ... ¿cómo puedo aislar un objeto cuando podría agregarse (por ejemplo) en una lista de arrays múltiple? Establecer 'object = null' eliminará todas las referencias? – manix

+1

@manix: no, no lo hará. eso simplemente anularía la referencia llamada 'objeto' en el alcance actual. Debe eliminar este objeto de todas estas listas o de cualquier otro contenedor. – haylem

+0

@halem ¿Las listas de matrices múltiples son de corta o larga duración? Si son de corta vida, entonces no hay problema. Una vez que el arraylist ya no es accesible, el recolector de basura hará su magia. OTH si el arraylist es de larga vida, entonces todos sus elementos serán alcanzables durante su ciclo de vida a menos que haga algo. Recomiendo listas de arreglos de vida corta. – emory

6

El objetivo de la recolección de basura de Java es que no tiene que hacer nada. La recolección de basura está hecha para ti.

+0

Nuff dijo lol. Además, en tu caso, veo por qué estás preocupado. Pero piénselo de esta manera, o 2 escenarios realmente. 1, el desarrollador que creó el código que está utilizando no documenta posibles fugas de memoria, en cuyo caso no se puede hacer mucho excepto usar otra cosa. 2, lee la documentación que explica esto y te ayuda a evitar cualquier problema como el que hablas. ASÍ QUE generalmente no te preocupes demasiado a menos que sospeches que algún código está ralentizando tu aplicación. – Andy

+0

¿qué hay de usar un método "proxy" como @Martinsos dijo? para eliminar sus referencias – manix

1

Asigne todas las referencias que desee que el GC recoja al null.

+0

haga lo mismo si el obj contiene un objeto de hilo en ejecución o un temporizador? – suiwenfeng

1

Lo que podrías hacer es hacer una clase intermedia. Por ejemplo, si tiene una instancia de la clase A, para la cual tiene muchas referencias y desea eliminarla, pero muchas referencias lo dificultan, puede hacer lo siguiente: crear una instancia de la clase B que no contenga nada más que referencia a instancia de clase A (como algún tipo de proxy). Ahora tendrá muchas referencias a la instancia de la clase B, pero solo una referencia a la instancia de la clase A, que puede eliminar fácilmente y el recolector de basura recopilará la instancia de la clase A.

La imagen muestra una diferencia al usar el proxy (instancia de la clase B): ahora solo se debe eliminar una referencia.

enter image description here

+0

¡servicial! Ahora es más claro :) – manix

0

En su mayor parte, GC va a hacer su magia en el momento oportuno.

Puede tener una situación en la que, por ejemplo, una vista esté observando un modelo y desee deshacerse de la vista pero conservar el modelo. En ese caso, deberá recordar los objetos de devolución de llamada del observador y eliminarlos cuando descarte la vista. No necesariamente tiene que tener campos especiales para cada observador; un conjunto de tareas que anula el registro de una devolución de llamada estará bien. O, de forma más compleja, puede tener una capa de indirección transitoria sobre el modelo que se descomprime de la subyacente. Sugiero evitar cosas raras con referencias débiles de un tipo u otro.

En caso de que tenga finalizadores (o requiera algún tipo de desalojo de mapa débil), como presumiblemente con un java.awt.Frame, es posible que desee una capa de indirección entre el recurso y la memoria que simplemente puede ser anulado