Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>(Yes, this is an old question, but the results were sort of interesting so I poked at it a bit.)</p> <p>The <code>Object.clone()</code> method needs to make a full bitwise copy of an object. To do so, it needs to know how big an object is. If you look at <code>dvmCloneObject()</code>, you see that it uses one method for arrays and a different method for objects.</p> <p>For arrays, it calls <code>dvmArrayObjectSize()</code>, which multiplies the array length by the element width (1, 2, 4, or 8), and then adds the offset of the array data from the start of the object. Every object has an 8-byte header; arrays have a 4-byte width and include an additional 4 bytes of padding to ensure that 64-bit values are aligned properly. So for a 5-element array of <code>short</code>, it would be 16 + 5 * 2.</p> <p>For ordinary objects, it just uses the <code>objectSize</code> field in the class object. This is set by a rather complicated function called <code>computeFieldOffsets()</code>. That function ensures that all object references come first (so the GC can skip around less when scanning), then follows that with all of the 64-bit fields. To ensure that the 64-bit fields are properly aligned, it may move one of the 32-bit primitive fields up to pad things out. (If there's no appropriate 32-bit field, you just get 4 bytes of padding.)</p> <p>I should add: all fields are 32-bit, except <code>long</code> and <code>double</code>, which are 64-bit. Object references are 32-bit.</p> <p>So it's tricky to say exactly how big a non-array object will be, but in general you take the 8-byte object header, sum up the widths of the additional fields, and round up to the next multiple of 8 bytes -- the last because all objects must be 64-bit aligned.</p> <p>So that's the theory. To see it in practice, I added this to <code>dvmCloneObject()</code>:</p> <pre><code>ALOGD("class=%s size=%d", clazz-&gt;descriptor, clazz-&gt;objectSize); </code></pre> <p>and saw logcat output like:</p> <pre><code>D dalvikvm: class=Ljava/util/Locale; size=24 D dalvikvm: class=Ljava/util/Date; size=16 </code></pre> <p>Locale has 4 reference fields, Date has one <code>long</code> field, so these values match expectations.</p> <p>Ideally, that's exactly how much space would be required. However, the object is allocated with <code>mspace_calloc()</code>, which adds another 4 or (sometimes) 8 bytes of overhead. So the <em>actual</em> space required for the values above would be 32 and 24, which matches your experimental results.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload