manejo - garbage collector java
¿Cómo se distribuyen los objetos Java en memoria en Android? (1)
dalvik/vm/oo/Object.h
es tu amigo aquí. El comentario para struct Object
dice:
/* * There are three types of objects: * Class objects - an instance of java.lang.Class * Array objects - an object created with a "new array" instruction * Data objects - an object that is neither of the above * * We also define String objects. At present they''re equivalent to * DataObject, but that may change. (Either way, they make some of the * code more obvious.) * * All objects have an Object header followed by type-specific data. */
java.lang.Class
objetos java.lang.Class
son especiales; su diseño está definido por la estructura Object.h
en Object.h
. Los objetos de matriz son simples:
struct ArrayObject : Object {
/* number of elements; immutable after init */
u4 length;
/*
* Array contents; actual size is (length * sizeof(type)). This is
* declared as u8 so that the compiler inserts any necessary padding
* (e.g. for EABI); the actual allocation may be smaller than 8 bytes.
*/
u8 contents[1];
};
Para las matrices, los anchos están en vm/oo/Array.cpp
. Los booleanos tienen un ancho de 1, los objetos tienen la longitud de sizeof(Object*)
(generalmente 4), y todos los demás tipos primitivos tienen su longitud esperada (empaquetada).
Los objetos de datos son realmente simples:
/*
* Data objects have an Object header followed by their instance data.
*/
struct DataObject : Object {
/* variable #of u4 slots; u8 uses 2 slots */
u4 instanceData[1];
};
El diseño de un DataObject
(todas las instancias de clase que no son de clase) se rige por computeFieldOffsets
en vm/oo/Class.cpp
. Según el comentario allí:
/*
* Assign instance fields to u4 slots.
*
* The top portion of the instance field area is occupied by the superclass
* fields, the bottom by the fields for this class.
*
* "long" and "double" fields occupy two adjacent slots. On some
* architectures, 64-bit quantities must be 64-bit aligned, so we need to
* arrange fields (or introduce padding) to ensure this. We assume the
* fields of the topmost superclass (i.e. Object) are 64-bit aligned, so
* we can just ensure that the offset is "even". To avoid wasting space,
* we want to move non-reference 32-bit fields into gaps rather than
* creating pad words.
*
* In the worst case we will waste 4 bytes, but because objects are
* allocated on >= 64-bit boundaries, those bytes may well be wasted anyway
* (assuming this is the most-derived class).
*
* Pad words are not represented in the field table, so the field table
* itself does not change size.
*
* The number of field slots determines the size of the object, so we
* set that here too.
*
* This function feels a little more complicated than I''d like, but it
* has the property of moving the smallest possible set of fields, which
* should reduce the time required to load a class.
*
* NOTE: reference fields *must* come first, or precacheReferenceOffsets()
* will break.
*/
Por lo tanto, los campos de superclase vienen primero (como es habitual), seguidos de los campos de tipo de referencia, seguidos de un solo campo de 32 bits (si está disponible, y si se requiere relleno porque hay un número impar de campos de referencia de 32 bits) seguido de 64 campos de bits Siguen los campos regulares de 32 bits. Tenga en cuenta que todos los campos son de 32 o 64 bits (las primitivas más cortas se rellenan). En particular, en este momento, la máquina virtual no almacena los campos de bytes / caracteres / cortos / booleanos con menos de 4 bytes, aunque ciertamente podría admitir esto en teoría.
Tenga en cuenta que todo esto se basa en la lectura del código fuente de Dalvik desde el commit 43241340
(6 de febrero de 2013). Dado que este aspecto de la VM no parece estar documentado públicamente, no debe confiar en que esta sea una descripción estable del diseño de objetos de la VM: puede cambiar con el tiempo.
Estoy bastante familiarizado con el diseño de objetos en el montón en HotSpot, pero no tanto para Android.
Por ejemplo, en una JVM HotSpot de 32 bits, un objeto en el montón se implementa como un encabezado de 8 bytes, seguido de los campos del objeto (un byte para boolean
, cuatro bytes para una referencia y todo lo demás como se esperaba), establecido en algún orden específico (con algunas reglas especiales para campos de superclases) y rellenado a un múltiplo de 8 bytes.
He investigado un poco, pero no puedo encontrar ninguna información específica de Android.
(Estoy interesado en optimizar algunas estructuras de datos extremadamente utilizadas para minimizar el consumo de memoria en Android).