views:

421

answers:

11

Why does the following line

    Object[] objects = new Object[10000000];

result in a lot of memory (~40M) being used by the JVM? Is there any way to know the internal working of the VM about arrays?

Manu

+15  A: 

Well, that allocates enough space for 10000000 references, as well as a small amount of overhead for the array object itself.

The actual size will depend on the VM - but it's surely not surprising that it's taking up a fair amount of memory... I'd expect at least 40MB, and probably 80MB on a 64-bit VM, unless it's using compressed oops for arrays.

Of course, if you populate the array with that many distinct objects, that will take much, much more memory... but the array itself still needs space just for the references.

Jon Skeet
+3  A: 

One of the principal reasons arrays are used so widely is that their elements can be accessed in constant time. This means that the time taken to access a[i] is the same for each index i. This is because the address of a[i] can be determined arithmetically by adding a suitable offset to the address of the head of the array. The reason is that space for the contents of an array is allocated as a contiguous block of memory.

tdtje
+2  A: 

You are creating ten million references to an object. A reference is at least 4 bytes; IIRC in Java it might be 8, but I'm unsure of that.

So with that one line you're creating 40 or 80 megabytes of data.

Randolpho
+2  A: 

You are reserving space for ten million references. That is quite a bit.

gpeche
+2  A: 

It results in a lot of memory being used because it needs to allocate heap space for 10 million objects and their associated overhead.

To look into the internal workings of the JVM, you can check out its source code, as it is open source.

Jeff
the heap space is not allocated while the objects are not created using new, isn't it ?
Manuel Selva
That's a general way of looking at it because to create an object, you use `new`, and then it goes on the heap. But to be more specific: The heap contains objects and their instance variables (including primitives that aren't created with `new`). Array values go on the heap too.
Jeff
@Manuel Selva: Yes, the heap space for the Objects *contained* in the array is only allocated when you create the objects. The array itself however also needs space, to hold the object references, as explained in the other answers. The space for an array is allocated right away, even though it only contains nulls.
sleske
+2  A: 

Your array has to hold 10 million object references, which on modern platforms are 64 bit (8 byte) pointers. Since it is allocated as a contiguous chunk of storage, it should take 80 million bytes. That's big in one sense, small compared to the likely amount of memory you have. Why does it bother you?

Ira Baxter
+12  A: 

What do you mean by "a lot of memory"? You allocating 10000000 pointers, each taking 4 bytes(on 32 bit machine) - this is about 40mb of memory.

Alex Reitbort
Yup... hello, basic math! It's taking the exact amount of memory it's supposed to.
Pete
+2  A: 

It creates an array with 10.000.000 reference pointers, all initialized with null.

What did you expect, saying this is "a lot"?


Further reading

Andreas_D
A: 

Why don't you explain what you are trying to do? That sounds just weird.

luiscolorado
Wow! My first negative vote... that hurts!
luiscolorado
10 million objects references are just a lot. Arrays are good when you need quick access *and* you have the element number to access an element. Usually databases are better suited to handle such number of records, so that's why I ask: what are you trying to do? There might be better approaches to your project (but we just don't know).
luiscolorado
+1  A: 

According to this site, the memory usage for arrays is a 12 bytes header + 4 bytes per element. If you declare an empty array of Object holding 10M elements, then you have just about 40MB of memory used from the start. If you start filling that array with actually 10M object, then the size increases quite rapidly.

From this site, and I just tested it on my 64-bit machine, the size of a plain Object is about 31 bytes, so an array of 10M of Object is just about 12 bytes + (4 + 31 bytes) * 10M = 350 000 012 bytes (or 345.78 MB)

If your array is holding other type of objects, then the size will be even larger.

I would suggest you use some kind of random access file(s) to hold you data if you have to keep so much data inside your program. Or even use a database such as Apache Derby, which will also enable you to sort and filter your data, etc.

Yanick Rochon
Why "4*31" instead of "4+31"?
Rotsor
oops, yeah fixed it. Thanks :)
Yanick Rochon
A: 

I may be behind the times but I understood from the book Practical Java that Vectors are more efficient and faster than Arrays. Is it possible to use a Vector instead of an array?

Jerry Carter
Using a vector won't make it less small in term of resources. In fact, it can be even worst as a Vector make internal use of an array and that array is resized as more item are inserted + 1 element :)
Yanick Rochon
very interesting - didn't know that. Thanks!
Jerry Carter
A good discussion on object memory in Java (agrees with your assesment, Yanick) http://www.javaspecialists.eu/archive/Issue029.html
Jerry Carter
You can't say that Vectors are always more efficient - that depends on the way they are used. Vectors (better: Lists - use the interface) are however much easier to use (resizable, you can insert anywhere etc.), so they are generally preferred.
sleske