Как объекты Java размещаются в памяти на Android?
Я хорошо знаком с расположением объектов в куче в HotSpot, но не так много для Android.
Например, в 32-разрядной JVM HotSpot объект в куче реализован в виде 8-байтового заголовка, за которым следуют поля объекта (один байт для boolean
четыре байта для ссылки и все остальное, как и ожидалось), расположенные в определенном порядке (с некоторыми специальными правилами для полей из суперклассов), и дополненные до 8 байтов.
Я провел некоторое исследование, но не могу найти какую-либо специфическую для Android информацию.
(Я заинтересован в оптимизации некоторых чрезвычайно широко используемых структур данных, чтобы минимизировать потребление памяти на Android.)
1 ответ
dalvik/vm/oo/Object.h
твой друг здесь Комментарий для struct Object
говорит:
/* * 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
объекты особенные; их расположение определяется ClassObject
структурировать в Object.h
, Объекты массива просты:
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];
};
Для массивов ширина в vm/oo/Array.cpp
, Булевы значения ширины 1, объекты имеют sizeof(Object*)
длина (обычно 4), а все другие примитивные типы имеют ожидаемую (упакованную) длину.
Объекты данных действительно просты:
/*
* 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];
};
Макет DataObject
(все экземпляры классов, не относящихся к классу) регулируется computeFieldOffsets
в vm/oo/Class.cpp
, Согласно комментарию там:
/*
* 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.
*/
Итак, поля суперкласса идут первыми (как обычно), за ними следуют поля ссылочного типа, за которыми следует одно 32-битное поле (если доступно, и если требуется заполнение, потому что существует нечетное количество 32-битных ссылочных полей), за которым следует 64-битные поля. Следуют обычные 32-битные поля. Обратите внимание, что все поля являются 32-битными или 64-битными (более короткие примитивы дополняются). В частности, в настоящее время виртуальная машина не хранит байтовые /char/short/ логические поля, используя менее 4 байтов, хотя, безусловно, теоретически это может поддерживать.
Обратите внимание, что все это основано на чтении исходного кода Dalvik с момента коммита 43241340
(6 февраля 2013 г.) Поскольку этот аспект виртуальной машины, по-видимому, не документирован публично, не следует полагаться на то, что он является стабильным описанием структуры объекта виртуальной машины: он может изменяться со временем.