Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Memory usage - primitives [duplicate]

Quoting the following from Algorithms 4th edition

"For example, if you have 1GB of memory on your computer (1 billion bytes), you cannot fit more than about 32 million int values or 16 million double values in memory at one time."

int - 4 bytes

32 million x 4 = 128 million bytes

Help me understand, why we can't fit 32 million int values, the above 128 million bytes is about 1/10 of the overall memory consumption of 1GB or 1 billion bytes.

like image 902
MasterV Avatar asked Aug 16 '13 16:08

MasterV


People also ask

How primitives and constants are stored in memory in Java?

The eight primitives defined in Java are int, byte, short, long, float, double, boolean and char. These aren't considered objects and represent raw values. They're stored directly on the stack (check out this article for more information about memory management in Java).

In which memory primitive data types are stored?

Stack memory stores primitive types and the addresses of objects. The object values are stored in heap memory.

How memory is allocated for primitive and non-primitive data types?

➲ In Java, all data type for primitive type variables is stored on the stack. ➲ For reference data types, the stack holds a pointer to the object on the heap.


2 Answers

That depends on how you organize your data. In Java, every object has an overhead, this is JVM dependent, but typically 8 or 16 bytes. So if you wrap every int value into an object (like Integer), then you may exceed 1GB. But, if you allocate it as an int[] array, then it should fit into 1GB easily.

And, this is not strictly related to the question, but reflecting to @Anony-Mousse's comment, there are JVMs for microcontrollers, and I am pretty sure that object size is below 8 bytes in those JVMs (though I didn't find exact data).

like image 128
Katona Avatar answered Oct 05 '22 22:10

Katona


Just as @Katona said, it depends on whether you store primitve integers or wrapped integers.

An int needs 4 bytes, a double needs 8 bytes, but both Integer and Double objects in the usual Hotspot VM need 16 bytes.

Assuming that you store them as Integer[], you need 4 additional bytes for each object reference.

Now if you use e.g. a TreeSet or a HashSet things become substantially worse. These also will requrie an Entry object, which (on 32 bit, or with compressed pointers) should add another 16 bytes, plus 4 (8 without compressed pointers on 64 bit) bytes for the object reference in the internal storage.

So if you are storing integers in a TreeSet<Integer> you might well run out of memory with just 28 million integers and 1 GB of RAM.

The other aspect is that obviously not all of your memory is available for storing object data. Java also needs memory for housekeeping, classloaders and some memory is just "wasted" at segment borders, and kept ready for future use. Assuming that e.g. only 50%-66% are available for your "own" disposal and you have the object overhead, the numbers above may be correct, and happen to cause problems in practise, not theory.

like image 21
Has QUIT--Anony-Mousse Avatar answered Oct 05 '22 22:10

Has QUIT--Anony-Mousse