I'm in the process of moving a project from Java 8 to Java 11 and I've hit
a stumbling block on what I thought should be a rather simple problem.
During runtime, how do I get the size of an object in memory?  Here are the
methods I've found so far:

1. The  Unsafe way.

Use sun.misc.Unsafe to get the declared fields and find the field with the
largest objectFieldOffset. Use the sun.arch.data.model to calculate the
machine word (WORD = NR_BITS/8) size.  Return ((maxOffset / WORD ) +1 ) *
WORD.  This is reasonably accurate but obviously not friendly in Java 11.
Found on Stackoverflow [1].

2. Use java.lang.instrument.Instrumentation

Been around for a long time [2].  However, this requires configuring
special manifests for the project.  Not very friendly for application
deployment, etc.

3. Use before/after memory consumption

Also mentioned in various stack overflow responses is the idea of calling
the garbage collector and memory usage before and after allocating and
using the difference for the size.  I suppose this had the advantage of
providing a deeper estimate of the object.  However, with other threads
doing work in the background this is mostly luck that we get the right
answer.

4. Add up the base types.

Also observed, investigate the types of each field and estimate the size of
the object based on the size of an arbitrary header length plus sizes for
each boolean, int, long, reference, etc.  This misses padding added by the
JVM, so not as accurate as using UNSAFE in 1.


A few questions:
Is there another method I've missed?
Have I missed an obvious method that has been added in Java 11+?
Is there any plans to add anything in a future release?


[1]
https://stackoverflow.com/questions/9368764/calculate-size-of-object-in-java
[2]
https://amitstechblog.wordpress.com/2011/05/19/estimating-the-memory-usage-of-a-java-object/

Reply via email to