Java
Raiting:
2

Size of Java objects


Do you know how much memory the string has? I have heard all kinds of answers to this question, ranging from "do not know" to "string has 2 bytes". Here are some more questions: How much space does empty string take? How much space does the class object of Integer take? How much space will take your own class object with three Integer fields? It is funny, but none of my Java programmer friends could answer these questions ... Most of us do not need it, and nobody will think about it in the real java projects. After all, this is the same as you would not know the engine capacity of vehicle that you drive every day. You can be a great driver and did not even know what 2.4 or 1.6 means on your car. But I am sure that there are few people who are not familiar with the meaning of these numbers. So why do java programmers know so little about this part of their tool?

Integer vs int

We all know that in java - everything is an object. Except, perhaps, primitives and references to the objects themselves. Let us consider two typical situations:

/ / The first case
int a = 300;
/ / The second case
Integer b = 301;

The difference is huge in these simple lines as for the JVM and the OOP. In the first case, it is 4-byte variable that contains the value from the stack. In the second, it is a reference variable and the object to which the variable is referenced. Consequently, if in the first case, we know definitely that the occupied size is equal:

sizeOf(int)
In the second case:

sizeOf(reference) + sizeOf(Integer)
In the second case, the consumed memory size is approximately in 5 times more, depending on the JVM. Now let's figure out why the difference is so huge.

The object structure

Before we will determine the consumed memory size, we should find out what the JVM keeps for each object:

• The object header.
• The memory for primitive types.
• The memory for reference types.
• Offset / alignment - in fact, these are a few unused bytes that are placed after the data object itself. This is done in order that an address in memory was always a multiple of machine word, to speed up the memory read + reduce the number of bits for a pointer to an object. It is also worth noting that in java a size of any object is multiple of 8 bytes!

The structure of object header

Each class instance has a header. Each header for most of JVM (Hotspot, openJVM) consists of two machine words. In the case of 32-bit system, the header size is 8 bytes, in the case of 64-bit system, respectively is 16 bytes. Each header will keep the following information:

• Hash Code - each object has a hash code. By default, the result of calling method Object.hashCode() will return the address of the object in memory, though some garbage collectors can move objects in memory, but the hash code is always the same as the space in the object's header that can be used to store the original values of the hash code.
• Garbage Collection Information - each java object contains the information needed for the memory management. This is often one or two bits of the flag, but it can be some combination of bits to store the number of references to the object.
• Type Information Block Pointer - contains information about the type of object. This block contains information about the virtual method table, a pointer to an object that represents the type and pointers to some additional structure for more efficient call interfaces, and dynamic type checking.
• Lock - each object contains information about the locking. This may be a pointer to an object or direct representation of the locking.
• Array Length - if the object - an array, then the header extends by 4 bytes to store the length of the array.

Java specification

It is known that primitive data types in Java have a predetermined size, it requires a specification for a portable code. More detailed information is well described in the link above. Each object has a header. In other words, the sizes of instances of your classes may be different from one JVM to another. Actually, to make it simple, I will give examples on a 32-bit Oracle HotSpot JVM. Now let's look at the most used classes such as Integer and String.

Integer and String

So, let's try to figure out how much will take an object of class Integer in our 32-bit HotSpot JVM. In order to do that it is needed to look into the class itself, we are interested in all the fields that are not declared as static. We see only - int value. Now, based on the information above, we get:

Header: 8 bytes
Field int: 4 bytes
Alignment for the multiplicity of 8 : 4 bytes
Total: 16 bytes

Now let us look at the class string:

private final char value[];
private final int offset;
private final int count;
private int hash;

We calculate the size:

Header: 8 bytes
Fields int: 4 bytes * 3 == 12 bytes
The reference variable to an object of array: 4 bytes
Total: 24 bytes

Well, that's not all ... Because the string contains a reference to an array of characters, in fact, we are dealing with two different objects - an class object of string and an array that stores the string. It is okay in terms of OOP, but if we look at it from memory point, then to that size we have to add another size allocated to the characters of array. And this is another 12 bytes for the object of array + 2 bytes for every character of the string. Of course, we do not forget to add the alignment for the multiplicity of 8 bytes. So the new String (“a”) results in:

new String ()
Header: 8 bytes
Fields int: 4 bytes * 3 == 12 bytes
The reference variable to an object of array: 4 bytes
Total: 24 bytes

new char [1]
Header: 8 bytes + 4 bytes for the array length == 12 bytes
Primitives char: 2 bytes * 1 == 2 bytes
Alignment for the multiplicity of 8 : 2 bytes
Total: 16 bytes

Total, the new String ("a") == 40 bytes

Importantly, the new String ("a") and new String («aa») will take the same size of memory. It is important to understand. It is a typical example of use of this fact in our favor - hash field in the class String. If it was not there, then a string object would take 24 bytes due to the alignment. And so it turns out that for these 4 bytes were found very good use.

Reference size

I would like to say a little bit of reference variables. The size of reference in the JVM depends on its capacity for optimization. Therefore, the reference size is 4 bytes in the 32-bit JVM, and it is 8 bytes in the 64-bit. This condition is not required.

Grouping fields

It should also be noted that the JVM makes a preliminary grouping of object fields. This means that all the fields of a class are placed in memory in a certain order, and not as declared. The order of grouping is as follows:

• 1. 8 byte types (double and long)
• 2. 4 byte types (int and float)
• 3. 2 byte types (short and char)
• 4. One byte types (boolean, and byte)
• 5. Reference variables

Why do we need all this?

Sometimes a situation arises where you need to estimate the approximate size of memory to store various objects, such as vocabulary. Also, it is potentially possible way to optimize, especially in environment where an access to its settings is not available.

Summary

The subject of memory in java is very interesting and extensive. When I started writing this article, I thought just to give a couple of examples with conclusions. But the farther and deeper I dig, the more interesting it becomes. In general, it is useful to know how memory is allocated for objects, because it will help you to save the memory, prevent similar problems or optimize your program in places where it seemed impossible. I hope you found the article interesting.
ZimerMan 8 february 2012, 14:12
Vote for this post
Bring it to the Main Page
 

Comments

Leave a Reply

B
I
U
S
Help
Avaible tags
  • <b>...</b>highlighting important text on the page in bold
  • <i>..</i>highlighting important text on the page in italic
  • <u>...</u>allocated with tag <u> text shownas underlined
  • <s>...</s>allocated with tag <s> text shown as strikethrough
  • <sup>...</sup>, <sub>...</sub>text in the tag <sup> appears as a superscript, <sub> - subscript
  • <blockquote>...</blockquote>For  highlight citation, use the tag <blockquote>
  • <code lang="lang">...</code>highlighting the program code (supported by bash, cpp, cs, css, xml, html, java, javascript, lisp, lua, php, perl, python, ruby, sql, scala, text)
  • <a href="http://...">...</a>link, specify the desired Internet address in the href attribute
  • <img src="http://..." alt="text" />specify the full path of image in the src attribute