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.