22

私は、HotSpot のヒープ上のオブジェクトのレイアウトにはかなり精通していますが、Android についてはあまり詳しくありません。

たとえば、32 ビットの HotSpot JVM では、ヒープ上のオブジェクトは 8 バイトのヘッダーとして実装され、その後にオブジェクトのフィールドが続きます (1 バイトはboolean、参照は 4 バイト、その他は想定どおり)。特定の順序で (スーパークラスのフィールドにはいくつかの特別な規則を使用して)、8 バイトの倍数になるようにパディングされます。

調べてみましたが、Android 固有の情報は見つかりませんでした。

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

4

1 に答える 1

20

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構造体 inによって定義され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];
};

DataObjecta (すべての非 Class クラス インスタンス)のレイアウトはin によって管理さcomputeFieldOffsetsvm/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.
 */

そのため、スーパークラス フィールドが最初に (通常どおり)、その後に参照型フィールドが続き、その後に 1 つの 32 ビット フィールドが続き (利用可能な場合、および 32 ビット参照フィールドが奇数個あるためにパディングが必要な場合)、その後に 64 が続きます。 -ビット フィールド。通常の 32 ビット フィールドが続きます。すべてのフィールドが 32 ビットまたは 64 ビットであることに注意してください (短いプリミティブはパディングされます)。特に、現時点では、VM は 4 バイト未満を使用して byte/char/short/boolean フィールドを格納しませんが、理論上はこれを確実にサポートできます。

これはすべて、コミット43241340(2013 年 2 月 6 日) 時点での Dalvik ソース コードの読み取りに基づいていることに注意してください。VM のこの側面は公式に文書化されていないように見えるため、これを VM のオブジェクト レイアウトの安定した説明として当てにしないでください。時間の経過とともに変化する可能性があります。

于 2013-02-08T22:18:00.063 に答える