Android Dalvik 中的对象大小

Alphonse68R 9年前
   <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>