Android Dalvik 中的对象大小
Alphonse68R
10年前
<h3>Size of data</h3> <ul> <li> <p>Size of reference</p> <p>In HotSpot, an object reference is 4 bytes in 32 bit JVM, 8 bytes in 64 bit JVM with <code>-UseCompressedOops</code> and 4 bytes with<code>+UseCompressedOops</code>. In Dalvik, reference is always 4 bytes.</p> </li> <li> <p>Size of primitive data type</p> <p>The size of the primitive data type is fixd as follows:</p> <table> <thead> <tr> <th>Data type</th> <th>32 bit JVM</th> <th>64 bit +UseCompressedOops</th> <th>64bit -UseCompressedOops</th> </tr> </thead> <tbody> <tr> <td>Object reference</td> <td>4</td> <td>4</td> <td>8</td> </tr> <tr> <td>boolean</td> <td>1</td> <td>1</td> <td>1</td> </tr> <tr> <td>byte</td> <td>1</td> <td>1</td> <td>1</td> </tr> <tr> <td>char</td> <td>2</td> <td>2</td> <td>2</td> </tr> <tr> <td>short</td> <td>2</td> <td>2</td> <td>2</td> </tr> <tr> <td>int</td> <td>4</td> <td>4</td> <td>4</td> </tr> <tr> <td>float</td> <td>4</td> <td>4</td> <td>4</td> </tr> <tr> <td>long</td> <td>8</td> <td>8</td> <td>8</td> </tr> <tr> <td>double</td> <td>8</td> <td>8</td> <td>8</td> </tr> </tbody> </table> <p>But the size of the primitive type data is very diffrent in Dalvik.</p> <p>The size of a primitive data type is not the same when it is a field of object or a variable from when it is an element in Array.</p> <table> <thead> <tr> <th>Data type</th> <th>Size as field / variable</th> <th>Size in Array</th> <th>32 bit JVM</th> <th>64 bit +</th> <th>64bit -</th> </tr> </thead> <tbody> <tr> <td>Object reference</td> <td>4</td> <td>4</td> <td>4</td> <td>4</td> <td>8</td> </tr> <tr> <td>boolean</td> <td>4</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td> </tr> <tr> <td>byte</td> <td>4</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td> </tr> <tr> <td>char</td> <td>4</td> <td>2</td> <td>2</td> <td>2</td> <td>2</td> </tr> <tr> <td>short</td> <td>4</td> <td>2</td> <td>2</td> <td>2</td> <td>2</td> </tr> <tr> <td>int</td> <td>4</td> <td>4</td> <td>4</td> <td>4</td> <td>4</td> </tr> <tr> <td>float</td> <td>4</td> <td>4</td> <td>4</td> <td>4</td> <td>4</td> </tr> <tr> <td>long</td> <td>8</td> <td>8</td> <td>8</td> <td>8</td> <td>8</td> </tr> <tr> <td>double</td> <td>8</td> <td>8</td> <td>8</td> <td>8</td> <td>8</td> </tr> </tbody> </table> </li> </ul> <h3>Size of object</h3> <ul> <li> <p>Alignment</p> <p>In Dalvik, <strong>the boundary alignment of an object is also 8 bytes</strong>.</p> </li> <li> <p>Overhead of Object</p> <p>In HotSpot, as we know, the overhead of object is 8 bytes in 32 bit JVM, and 16 bytes in 64 bit JVM without <code>UseCompressedOops</code> and 12 bytes with <code>+UseCompressedOops</code>.</p> <p>In Dalvik, this is diffrent. The memory of an object looks like:</p> <pre> <code>+---------------------+----------------------+----------+ |overheade of Object | overhead of dlmalloc | data | +---------------------+----------------------+----------+ | 8 bytes | 4 or 8 bytes | | +---------------------+----------------------+----------+ </code></pre> <p>There is another overhead for dlmalloc, which will take 4 or 8 bytes.</p> <p>So an empty object will take 16bytes, 12 bytes for overhead, 4 bytes for padding.</p> <p>Here are some examples:</p> <pre> <code>class EmptyClass { } </code></pre> <p>Total size: 8 (Object overhead) + 4 (dlmalloc) = 12 bytes. For 8 bytes alignment, the final total size is 16 bytes.</p> <pre> <code>class Integer { int value; // 4 bytes } </code></pre> <p>The total size is: 8 + 4 + 4 (int) = 16 bytes.</p> <pre> <code>static class HashMapEntry<K, V> { final K key; // 4 bytes final int hash; // 4 bytes V value; // 4 bytes HashMapEntry<K, V> next; // 4 bytes } </code></pre> <p>The total size: 8 + 4 + 4 * 4 = 28 bytes. Total aligned is 32 bytes.</p> </li> </ul> <h3>Size of Array</h3> <p>The memory layout of Array looks like:</p> <pre> <code>+---------------------+----------------------+----------+---------+------+ |overheade of Object | overhead of dlmalloc | size | padding | data | +---------------------+----------------------+----------+---------+------+ | 8 bytes | 4 or 8 bytes | 4 bytes | 4 bytes | | +---------------------+----------------------+----------+---------+------+ </code></pre> <p>The alignment is also 8 bytes.</p> <p>So <code>byte[0]</code> will take: 8 + 4 + 4 + 4 = 20 bytes. The final size after alignment is 24 bytes.</p> <p><code>byte[0]</code> ~ <code>byte[4]</code> are all 24 bytes.</p> <p><code>char[0]</code> will also take 24 bytes. And from <code>char[0]</code> to <code>char[2]</code>, they are all 24 bytes.</p> <p>Size of <code>String</code></p> <p>String is defined as follows:</p> <pre> <code>class String { private final char[] value; // 4 bytes private final int offset; // 4 bytes private final int count; // 4 bytes private int hashCode; // 4 bytes } </code></pre> <p>Total size: 8 + 4 + 4 * 4 = 28 bytes. Total aligned is 32 bytes, which excludes the retained memory of char array(at least 24 bytes).</p> <p>So, even an empty String will still take at least 32 bytes of shadow heap and 24 bytes of retained heap.</p> <p>References</p> <p><a href="/misc/goto?guid=4959671944502368826">http://stackoverflow.com/questions/14738786/how-are-java-objects-laid-out-in-memory-on-android</a></p> <p><a href="/misc/goto?guid=4959671944601312840">http://stackoverflow.com/questions/9009544/android-dalvik-get-the-size-of-an-object</a></p> <p><a href="/misc/goto?guid=4959671944683424288">https://speakerdeck.com/romainguy/android-memories</a></p> <p><a href="/misc/goto?guid=4959671944767160484">http://www.slideshare.net/SOURCEConference/forensic-memory-analysis-of-androids-dalvik-virtual-machine</a></p> <p><a href="/misc/goto?guid=4959671944853308211">http://stackoverflow.com/questions/10824677/is-dalvik-even-more-memory-hungry-than-hotspot-in-terms-of-object-sizes/</a></p> <p>来源:http://www.liaohuqiu.net/posts/android-object-size-dalvik/</p>