¿Se puede recolectar una actividad si tiene variables de miembro estáticas a las que se hace referencia en otro lugar?

Supongamos que una actividad A tiene algunas variables de miembro estáticas, ya que la estática se carga en la memoria cuando la clase es cargada primero por VM y se queda alrededor, me pregunto qué le sucede a la actividad con respecto a la recolección de basura si otra clase B está sosteniendo cualquier variable estática de clase A ?. ¿No será recogido? ¿Se recogerá y la estática se inicializará a los valores iniciales?

Clases por ejemplo

public class Activity { public static int primitiveStatic = 42; public static Object objectStatic = new Object(); } public class B { public Object referenceField = null; } public class C { public int primitiveField = 0; } 

Un modelo simple de una instancia de objeto Java es un área de memoria que contiene, además del espacio para cada uno de sus miembros de instancia (no estática), alguna información administrativa que incluye una referencia a su objeto de clase. El objeto de clase (la entidad en memoria en tiempo de ejecución) contiene varias piezas de información sobre la clase, incluyendo el espacio (relevante para esta pregunta) para cada uno de los miembros estáticos de la clase. Tenga en cuenta que algo de esto depende de JVM.

La clave a tener en cuenta es que los miembros estáticos se almacenan en o con el objeto de clase en tiempo de ejecución (no en ningún objeto de instancia).

En las clases de ejemplo anteriores, el objeto de clase Activity en tiempo de ejecución tendría dos variables, una variable entera primitiveStatic ( primitiveStatic ) y una referencia de Object type ( objectStatic ). Cada instancia de la clase tendría su propio área de memoria distinta, conteniendo no mucho más que una sola referencia al objeto de clase. Una instancia de B tiene espacio para una sola referencia de objeto. Una instancia de C tiene espacio para un solo valor entero primitivo.

El recolector de basura puede eliminar y finalizar cualquier objeto en la memoria que es elegible para la recopilación. Esto se aplica también a objetos de clase, pero no es tan simple como para objetos de instancia, donde el objeto es elegible si simplemente no hay referencias a él. Los objetos de clase y campos estáticos rara vez son elegibles, pero en los casos en que la clase está descargada, lo son. Consulte esta documentación para obtener más información sobre la descarga de clase.

Creo que los casos en los que te estás preguntando incluyen estos:

Caso 1

 new Activity(); //or Activity a = new Activity(); a = null; 

Configuración del caso 1

Caso 1 después de la instalación y las asignaciones se completan.

La clase se carga, creando el objeto de clase y las variables estáticas como se describió anteriormente. Se crea una instancia, como se ha descrito anteriormente. La instancia es inmediatamente elegible para la recolección de basura. Cuando se recopila, la instancia se destruye, eliminando la referencia al objeto de clase. Si es el final del programa o en otros casos determinados, el objeto de clase también puede ser recolectado de basura, eliminando las variables primitiveStatic y objectStatic . En este caso, el new Object() que se refería ahora con objectStatic tampoco tiene referencias a él, y es a su vez elegible para la recolección de basura de la manera normal.

Caso 2

 B b = new B(); b.referenceField = Activity.objectStatic; 

Configuración del caso 2

Caso 2 después de la instalación y las asignaciones se completan.

Se crea una nueva instancia B (y el objeto de clase para la clase B ) como se describe anteriormente. Se carga la clase Activity y se crea el objeto de clase si no lo ha sido. El campo de referenceField en b se establece para referirse a la misma ubicación que el campo objectStatic , que se encuentra en o con el objeto de clase Activity . Si se descarga la clase Activity (sucede en algunos casos pero no es común), su objeto de clase se elimina como se describe en //1 . Esta vez, el new Object() todavía tiene una referencia a él, en b.referenceField , por lo que no es elegible para la recopilación. Nos quedamos con el objeto de clase B y el new Object() y una instancia, b , con una sola referencia a cada uno.

Caso 3

 Activity a = new Activity(); B b = new B(); b.referenceField = a.objectStatic; a = null; 

Configuración del caso 3

Caso 3 después de la instalación y las asignaciones se completan.

Se carga la clase Activity y se crea el objeto de clase si aún no lo están, como se describe anteriormente. Se crea una instancia, como se ha descrito anteriormente. Lo mismo para la clase B Al encontrar a referencia de clase y localizarla allí, la referencia estática objectStatic se obtiene de a y se asigna a b.referenceField . Esta es una asignación de copia del valor de referencia , por lo que no hay ninguna referencia entre b a Activity , pero b contiene ahora una referencia al new Object() construido por la clase Activity . a = null significa que la instancia de Activity mencionada inicialmente por a convierte en elegible para la recolección de basura. Su referencia al objeto de clase Activity se elimina. El objeto de clase Activity puede ser elegible para la recolección de basura. Si es así, los campos estáticos que contiene se borran. El new Object() refiere objectStatic ahora tiene una sola referencia, en b , por lo que no es elegible para la recolección de basura. Nos quedamos con este objeto, y el objeto de clase B , b que contiene una sola referencia a cada uno (idéntico al caso //2 )

Caso 4

 Activity a = new Activity(); C c = new C(); c.primitiveField = a.primitiveStatic; a = null; 

Configuración del caso 4

Caso 4 después de que la instalación y las asignaciones se hayan completado.

Al igual que en //3 , se carga la clase Activity y se crea el objeto de clase si no lo están, y se crea una instancia, como se ha descrito anteriormente. Lo mismo para la clase C Al encontrar a referencia de clase y localizarla allí, la primitiva static primitiva c.primitiveField se obtiene de a y se asigna a c.primitiveField . Esto es simplemente una asignación de copia , por lo que no hay referencia entre c y a Activity o. a = null significa que la instancia de Activity mencionada inicialmente por a convierte en elegible para la recolección de basura. Su referencia al objeto de clase Activity se elimina. El objeto de clase Activity puede ser elegible para la recolección de basura. Si es así, los campos estáticos que contiene se borran. El new Object() al que se objectStatic ahora por objectStatic no tiene referencias, por lo que es elegible para la recolección de basura. Nos quedamos con la instancia C , c , con un primitivo int valor de 42 en su primitiveField .

En todos estos casos, no se impide que ninguna instancia de objeto sea recolectada por otra cosa que tenga referencias a objetos también referidos por sus campos estáticos de clase (e incluso la clase y sus valores estáticos pueden ser recolectados en ciertas circunstancias), incluso cuando esos valores de campo son "propiedad" de la clase (por ejemplo, final e inicializado en y por la clase).

Lo que hay que tener en cuenta es que si el campo objectStatic es final , el objeto al que se refiere casi nunca será recopilado: la clase Activity debe descargarse para que sea elegible para la recopilación. Esto podría ser un problema si tiene un montón de referencias de objetos estáticos que no se utilizan después de la configuración del programa, ya que se quedan y llenar la memoria, aunque no se utilizan.

No se puede mantener una referencia a una variable estática (o cualquier variable) de una clase.

Uno sólo puede contener referencias a objetos , no la variable en sí.

P.ej,

 class MainActivity { public static Object obj = new Object(); } class B { private Object ref = MainActivity.obj; } 

En este caso, sólo el new Object() está siendo referenciado por B (y por lo tanto no puede ser GCed). No es la variable obj (o la clase MainActivity ) misma.

  • "Id no puede ser cero" - GoogleJsonResponseException 400 Petición incorrecta
  • ¿Por qué parece que tomar mucho tiempo para que este bloque sincronizado obtenga un bloqueo?
  • Lectura de metadatos EXIF ​​de jpeg de androide de devolución de llamada de imagen
  • Obtener la latitud y la longitud de una posición de clic en un mapas de forja 0.5.1 MapView
  • Evitar el reemplazo del método en tiempo de ejecución en Java
  • ¿Cómo analizar XML y almacenarlo en un mapa con SimpleXML?
  • HTTP Status 403 - No válido CSRF Token 'null' se encontró en el parámetro de solicitud
  • GetLocationOnScreen () vs getLocationInWindow ()
  • Cómo generar una consulta con la selección por valor del campo del objeto extraño
  • Recuperar ServerValue.Timestamp de Firebase en la aplicación de Android, cuando se envían los datos
  • Eliminar archivo de base de datos de la carpeta de activos
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.