2010-03-19 14 views
14

Sé que esta puede ser una pregunta tonta, pero mis antecedentes son más en C++ y administrar mi propia memoria.¿Se recolectan los tipos primitivos de basura en Android?

Actualmente estoy reduciendo cada asignación que puedo de uno de mis juegos para intentar y reducir la frecuencia de recolección de basura y percepción de "retraso", por lo que para cada variable que creo que es un Objeto (Cadena y Rect por ejemplo) Estoy asegurándome de crearlo antes de la mano en mi constructor y no crear variables temporales en las funciones de línea simple 10 ... (Espero que tenga sentido)

De todos modos, estaba trabajando aunque esta noche y me di cuenta de que puedo estar completamente equivocado sobre mi suposición sobre la recolección de basura y los tipos primitivos (int, boolean, float) son estas variables de tipo primitivo que creo en una función de 10 líneas que se llama 20 veces por segundo a mi problema de recolección de basura?

hace un año

Así que cada pocos segundos me gustaría ver un mensaje en Logcat como

GC liberados 4010/484064 bytes objetos en 101ms

Ahora veo que cada mensaje de 15-90 segundos más o menos ...

Así que para reformular mi pregunta: ¿Están incluidos los tipos primitivos (int, float, boolean, etc.) al ver este mensaje?

Respuesta

24

Los tipos primitivos no son objetos, por lo que no causan ninguna recolección de basura. Sin embargo, debes ser muy cuidadoso porque debido al boxeo, un tipo primitivo puede convertirse fácilmente en un objeto sin que lo hagas explícitamente.

Por ejemplo, si quiere un HashMap <> de llaves enteras, debería usar HashMap. Tenga en cuenta que debido a que "int" no es un objeto, no se puede usar en un contenedor. Entero es una versión de objeto de una primitiva int. Cuando se escribe código como este, un objeto entero se creará automáticamente para usted:

HashMap<Integer, Object> map = new HashMap<Integer, Object>(); 
int someNum = 12345; // no object created. 
map.put(someNum, null); // Integer object created. 

Tenga en cuenta que exactamente lo mismo sucederá si usted no utiliza los genéricos, pero aún más oculto:

HashMap map = new HashMap(); 
int someNum = 12345; // no object created. 
map.put(someNum, null); // Integer object created. 

Para esta situación particular, puede usar la clase SparseArray de Android, que es un contenedor de claves enteras primitivas.

6

Parece que la respuesta es no. Parece que las primitivas se colocan en la pila en Java y no en el montón y solo los objetos son basura. Encontré muchas referencias cortas a esto, revisa Wikipedia. Para leer un poco más, consulte un documento sobre una implementación de recolección de basura JVM que explica un poco más inequívocamente que las primitivas se almacenan en ubicaciones de memoria físicamente separadas para que no se incluyan por error en la recolección de basura here. Si tiene ganas de rozar, la página 4 es donde esto se explica más directamente.

aquí son las discusiones específicas androide indicando la GC only scans pointers y cómo it checks that

+0

Android no ejecuta una JVM estándar basada en pila, tiene su propia VM basada en registro. – mikerobi

2

[Nota: todavía no tengo todos los privilegios de comentarios, por lo que estoy agregando esto como una respuesta separada.]

Parece que los primitivos se ponen en la pila en Java y no en el montón y sólo los objetos son basura recogido.

Esto no es del todo exacto. Las primitivas pueden mantenerse en variables locales y también como campos estáticos o de instancia de clases. En el último caso, de hecho están almacenados en el montón, pero no tienen una "vida" propia y, en particular, no están separados del objeto en el que están contenidos.

Android no se ejecuta una JVM basado en pila estándar, que tiene su propio registro basado VM.

Esta es una afirmación verdadera, pero también es un poco engañosa y al margen de la pregunta original. De hecho, cuando un método llama a otro (y así sucesivamente), los marcos de activación de estos métodos se almacenan en una pila en la implementación de Dalvik. La diferencia es que, al observar un marco de activación aislado, los marcos de activación de Dalvik no contienen dentro de una pila de tamaño variable. En este sentido, la forma en que Dalvik organiza los marcos de activación se parece más a cómo se manejan para los lenguajes tradicionales tipo C (como C o C++).

+0

espere hasta que obtengan un N.P.E. debido a que no existe un constructor trivial predeterminado en un auto en una llamada a método, entonces intente perseguirlo usando la borradura de tipo como su única pista: la pregunta básica de ope tiene que ver con la creación de obj oculto y G.C. que es muy difícil de manejar para un paradigma de programación de estilo 'C' donde uno puede lograr lo que 'D' hace con ~ esto ... aunque el único enfoque efectivo es usar palabras clave sincronizadas y reutilizar obj ref (que va a obtener muchos aullidos de los tradicionalistas de Java establecidos) así que realmente lo que OP necesita hacer es leer Hans-J. Los comentarios de Boehm en gc.h –

Cuestiones relacionadas