1

Possible Duplicate:
Size of a byte in memory - Java

I read this in an article. I am just pasting as is:

  • The class takes up at least 8 bytes. So, if you say **new Object();** you will allocate 8 bytes on the heap.
  • Each data member takes up 4 bytes, except for long and double which take up 8 bytes. Even if the data member is a byte, it will still take up 4 bytes! In addition, the amount of memory used is increased in 8 byte blocks. So, if you have a class that contains one byte it will take up 8 bytes for the class and 8 bytes for the data, totalling 16 bytes (groan!).

Is it true Java byte allocates / takes 4 bytes? and empty class takes 8 bytes? Its confusing here as well.

Community
  • 1
  • 1
Kevin Rave
  • 13,876
  • 35
  • 109
  • 173

3 Answers3

5

As the Java specification does not mandate memory use, this depends on the JVM implementation you use.

Certainly, there will be a per-object overhead in all JVM implementations (to implement run time type checking, for instance). A JVM might elect to memory align fields (on some platforms, this gives a significant speedup when accessing the field).

However, I'd be greatly surprised if array members where padded for memory alignment, and can confirm that (at least on the oracle vm for windows) a boolean[] takes one byte per element.

Also, it's worth noting that the size of fields of reference type can be 8 bytes if you happen to address a suitably large heap.

To conclude: If you really want to know, measure memory consumption on your target JVM.

Edit: Out of curiosity, I wrote a small (inaccurate) benchmark:

class FourBytes {
    byte a,b,c,d;
}

public class Test {

    long usedBefore = used();

    long used() {
        return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
    }

    public void before() {
        System.gc();
        usedBefore = used();
    }

    public void after(String text) {
        long usedAfter = used();
        System.out.println(text + "\t" + new BigDecimal(usedAfter - usedBefore).movePointLeft(6) + " bytes");
        before();
    }

    {
        int max = 1000000;
        before();
        boolean[] bools = new boolean[max];
        after("boolean in array");

        char[] chars = new char[max];
        after("char in array   ");

        Object[] objects = new Object[max];
        after("reference type in array");

        for (int i = 0; i < max; i++) {
            objects[i] = new Object();
        }
        after("Object instance  ");

        Byte[] bytes = new Byte[max];
        before();
        for (int i = 0; i < max; i++) {
            bytes[i] = new Byte((byte) i);
        }
        after("Byte instance    ");


        Integer[] integers = new Integer[max];
        before();
        for (int i = 0; i < max; i++) {
            integers[i] = new Integer(i);
        }
        after("Integer instance");

        FourBytes[] fbs = new FourBytes[max];
        before();
        for (int i = 0; i < max; i++) {
            fbs[i] = new FourBytes();
        }
        after("FourBytes instance");

    }

    public static void main(String[] args) throws Exception {
        new Test();
    }
}

On

java version "1.7.0_02"
Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
Java HotSpot(TM) Client VM (build 22.0-b10, mixed mode, sharing)

it prints:

boolean in array    1.183624 bytes
char in array       2.091768 bytes
reference type in array 4.091768 bytes
Object instance     8.023664 bytes
Byte instance       16.133408 bytes
Integer instance    16.147312 bytes
FourBytes instance  16.142568 bytes
meriton
  • 68,356
  • 14
  • 108
  • 175
3

The class takes up at least 8 bytes. So, if you say new Object(); you will allocate 8 bytes on the heap.

In the OpenJDK/HotSpot JVM it will use 8 bytes on the 32-bit JVM and 16 bytes on the 64-bit JVM.

Each data member takes up 4 bytes, except for long and double which take up 8 bytes.

The minimum size is 1 byte not 4 bytes. References typucally use 4 bytes even on 64-bit JVMs.

Even if the data member is a byte, it will still take up 4 bytes!

That is a new idea. I don't know how you would come to that conclusion.

In addition, the amount of memory used is increased in 8 byte blocks.

Technically it aligned to 8 byte boundaries.

So, if you have a class that contains one byte it will take up 8 bytes for the class

It will take up 8 or 12 bytes for the header in 32-bit or 64-bit JVMs plus 1 byte for the byte and be rounded up to the next 8 byte boundary.

and 8 bytes for the data, totalling 16 bytes (groan!).

Indeed, but every possible Byte object is cached and auto-boxed, there is no reason you would do this. You never need to create a Byte explicitly or even implicitly.

Byte b = new Byte((byte) 1); // bad idea.
Byte b = 1; // simpler and more efficient
byte b = 1; // the most efficient option.
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
2

That is false, at least for the HotSpot JVM. There, a primitive byte field in a class will take one byte, but it is true that the size of an instance of a class starts at 8 bytes, and fields are grouped into chunks that take eight bytes apiece -- for example, you can't split a field across an 8-byte boundary.

See e.g. http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • +1 So a `Byte` object will take 16 bytes as this is the minimum. – Peter Lawrey Nov 09 '12 at 18:05
  • http://www.ibm.com/developerworks/library/j-codetoheap/ According to this article, an instance starts at 12 bytes. – hakunami Oct 09 '15 at 13:07
  • @hakunami That article specifies that the numbers vary for different JVM implementations. My numbers are correct for HotSpot. – Louis Wasserman Oct 09 '15 at 15:46
  • @LouisWasserman I am using `Java HotSpot(TM) 64-Bit Server VM`. If Object starts from 8 bytes is true, then I cant explain the test I did: An empty Object is 16 bytes in my machine(OX 10.11), if it starts at 8 bytes, and a chunk is 8 bytes, then an empty Object should be 8 bytes only. But if it starts at 12, then it will take one and a half chunk, which is 12, rounded to 16. This explains. Furthermore, I put two `char` which takes 2 bytes primitives in that Object, it still 16 bytes, change to 24 bytes until the third char is added. So, this proves an empty Object does start at 12 in HotSpot. – hakunami Oct 10 '15 at 02:21