2013-02-06 15 views
20

Jestem dość obeznany z układem obiektów na stercie w HotSpot, ale nie na Androida.W jaki sposób obiekty Java są układane w pamięci w systemie Android?

Na przykład w 32-bitowej wirtualnej maszynie wirtualnej HotSpot JVM obiekt na stercie jest zaimplementowany jako 8-bajtowy nagłówek, a następnie pola obiektu (jeden bajt dla boolean, cztery bajty dla odniesienia i wszystko inne jako oczekiwane), określone w określonej kolejności (z pewnymi specjalnymi regułami dla pól z nadklas) i wyniesione do wielokrotności 8 bajtów.

Zrobiłem kilka badań, ale nie mogę znaleźć żadnych informacji specyficznych dla systemu Android.

(Jestem zainteresowany optymalizacji kilka niezwykle szeroko stosowane struktur danych, aby zminimalizować zużycie pamięci na Androida).

+0

Czytałeś/widziałem to: https://sites.google.com/site/io/dalvik-vm-internals/ –

+0

Nie miałem, ale to nie ma potrzebnych informacji. Mówi o układzie APK i bajtode, ale nie o obiektach na stercie. –

+0

Dalvik wydaje się być w większości identyczny: 4 bajty klasy ptr, 4 bajty blokady, a następnie dane: https://android.googlesource.com/platform/dalvik/+/master/vm/oo/Object.h – Chris

Odpowiedz

17

dalvik/vm/oo/Object.h jest Twój przyjaciel tutaj. Komentarz do struct Object mówi:

/* 
* 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 obiekty są specjalne; ich układ jest zdefiniowany przez strukturę ClassObject w Object.h. obiekty tablicowe są proste:

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]; 
}; 

Dla tablic, szerokości są w vm/oo/Array.cpp. Booleany mają szerokość 1, obiekty mają długość (zazwyczaj 4), a wszystkie inne typy pierwotne mają swoją oczekiwaną (zapakowaną) długość.

obiekty danych są bardzo proste:

/* 
* 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]; 
}; 

Układ ciągu DataObject (wszystkie wystąpienia klasy non-Class) jest regulowana przez computeFieldOffsets w vm/oo/Class.cpp. Zgodnie z komentarzem tam:

/* 
* 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. 
*/ 

Więc, pola SuperClass kto pierwszy (jak zwykle), a następnie przez pola odniesienia typu, po jednym 32-bitowe pole (jeśli są dostępne, a jeśli potrzebna jest wyściółka ponieważ tam nieparzysta liczba 32-bitowych pól odniesienia), a następnie 64-bitowe pola. Powtarzane są regularne 32-bitowe pola. Zwróć uwagę, że wszystkie pola są 32-bitowe lub 64-bitowe (krótsze prymitywy są dopełniane). W szczególności w tym momencie VM nie przechowuje bajtów/znaków/krótkich/pól logicznych za pomocą mniej niż 4 bajty, choć z pewnością może to wspierać w teorii.

Należy pamiętać, że wszystko to opiera się na lekturze kodu źródłowego Dalvik po zatwierdzeniu 43241340 (6 lutego 2013 r.). Ponieważ ten aspekt VM nie wydaje się być publicznie udokumentowany, nie powinieneś polegać na tym, że jest to stabilny opis układu obiektu VM: może się on zmieniać z biegiem czasu.

Powiązane problemy