5

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.

MasterV
  • 1,162
  • 1
  • 13
  • 18

2 Answers2

4

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).

Community
  • 1
  • 1
Katona
  • 4,816
  • 23
  • 27
  • Typically 16 bytes. Do you know a VM where it only is 8 bytes? – Has QUIT--Anony-Mousse Aug 16 '13 at 18:18
  • @Anony-Mousse not really, I read this everywhere, but [here](http://kohlerm.blogspot.hu/2008/12/how-much-memory-is-used-by-my-java.html) it's stated that `java.lang.Object` has size 8 (2 x 4) bytes on a 32 bit jvm. I now it's not that useful (and might be outdated). – Katona Aug 16 '13 at 19:10
  • Or 12 bytes aligned to 16 bytes, meaning that the first int comes for free. – assylias Aug 16 '13 at 19:11
  • AFAICT, actually the second `int` in an object should come for free: An empty object should need 8 bytes (4 bytes type reference, 4 bytes for management information), and an object with one *or* two int fields should be 16 bytes (due to padding). On Hotspot VM, that is - other VMs may vary, I don't know about Dalvik, for example. – Has QUIT--Anony-Mousse Aug 16 '13 at 20:24
  • @Katona Thanks for the feedback. My question was regarding primitive int, and not an Integer object, and yes you are right about the object overhead. – MasterV Aug 18 '13 at 00:45
2

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.

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194