How to efficiently store small byte arrays in Java?

前端 未结 2 2038
时光说笑
时光说笑 2021-02-19 05:34

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

2条回答
  •  遇见更好的自我
    2021-02-19 05:58

    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.

提交回复
热议问题