2013-02-06 10 views
20

私は、HotSpotのヒープ上のオブジェクトのレイアウトにはかなり精通していますが、Androidではそれほど多くはありません。 32ビットのHotSpot JVMに例えば JavaオブジェクトはAndroidのメモリにどのようにレイアウトされていますか?

は、ヒープ上のオブジェクトは、(オブジェクトのフィールドに続いて、8バイトのヘッダとして実装されbooleanための1バイト、参考のために4バイト、およびなどの他のすべていくつかの特定の順序(スーパークラスからのフィールドのためのいくつかの特別なルール)でレイアウトされ、8バイトの倍数にパディングされます。

私はいくつかの調査をしましたが、Android固有の情報は見つかりませんでした。

(Iは、Android上でメモリ消費を最小限に抑えるために、いくつかの非常に広く使われているデータ構造の最適化に興味があります。)

+0

あなたはこれを読んだことがありますか:https://sites.google.com/site/io/dalvik-vm-internals/ –

+0

私はしませんでしたが、私が望む情報はありません。 APKとバイトコードのレイアウトについては言いますが、ヒープ上のオブジェクトについては言及していません。 –

+0

Dalvikはほとんど同じようです:4バイトクラスのptr、4バイトのロック、次にデータ:https://android.googlesource.com/platform/dalvik/+/master/vm/oo/Object.h – Chris

答えて

17

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オブジェクトは特別です。それらのレイアウトは構造体によって定義されています(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のレイアウト(すべての非Classクラスのインスタンス)vm/oo/Class.cppcomputeFieldOffsetsによって支配されています。そこコメントによれば、そこだから

/* 
* 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ビットであることに注意してください(より短いプリミティブは埋められます)。特に、現時点では、VMは4バイト未満のバイト/ char/short/booleanフィールドを格納しませんが、確かにこれを理論上サポートできます。

このすべては、コミット43241340(2013年2月6日)時点のDalvikソースコードの読み取りに基づいています。 VMのこの側面は一般的に文書化されていないように見えるので、VMのオブジェクトレイアウトの安定した記述であることを頼りにするべきではありません。

関連する問題