By small byte arrays I mean arrays of bytes with length from 10 up to 30.
By store I mean storing them in the RAM, not
OK, so if I understood correctly (please ask if not - will try to answer), there are a couple of things here. First is that you need the right tool for measurements and JOL is the only one I trust.
Let' start simple:
byte[] two = new byte[1];
System.out.println(GraphLayout.parseInstance(one).toFootprint());
This will show 24 bytes
(12
for mark
and class
words - or Object headers + 4 bytes padding), 1 byte
for the actual value and 7 bytes for padding
(memory is 8 bytes aligned).
Taking this into consideration, this should be a predictable output:
byte[] eight = new byte[8];
System.out.println(GraphLayout.parseInstance(eight).toFootprint()); // 24 bytes
byte[] nine = new byte[9];
System.out.println(GraphLayout.parseInstance(nine).toFootprint()); // 32 bytes
Now let's move to two dimensional arrays:
byte[][] ninenine = new byte[9][9];
System.out.println(GraphLayout.parseInstance(ninenine).toFootprint()); // 344 bytes
System.out.println(ClassLayout.parseInstance(ninenine).toPrintable());
Since java does not have true two dimensional arrays; every nested array is itself an Object (byte[]
) that has headers and content. Thus a single byte[9]
has 32 bytes
(12
headers + 4
padding) and 16 bytes
for content (9 bytes
for actual content + 7 bytes
padding).
The ninenine
object has 56
bytes total: 16
headers + 36
for keeping the references to the nine objects + 4 bytes
for padding.
Look at the produced sample here:
byte[][] left = new byte[10000][10];
System.out.println(GraphLayout.parseInstance(left).toFootprint()); // 360016 bytes
byte[][] right = new byte[10][10000];
System.out.println(GraphLayout.parseInstance(right).toFootprint()); // 100216 bytes
That's a 260% increase; so by simply changing to work the other way around you can save a lot of space.
But the deeper problem is that every single Object in Java has those headers, there are no headerless objects yet. They might appear and are called Value Types. May be when that is implemented - arrays of primitives at least would not have this overhead.