4

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 workings of the VM when allocating arrays?

dimo414
  • 47,227
  • 18
  • 148
  • 244
Manuel Selva
  • 18,554
  • 22
  • 89
  • 134
  • 1
    How much is a lot of memory? And how much did you expect to be consumed? – Malcolm Sep 15 '10 at 15:14
  • @Malcolm: excellent question. These days, we don't think 40MB is all that much memory, do we? Back in the day, however.... – Randolpho Sep 15 '10 at 15:15
  • 2
    Well, it has just been said in the answers, if it is 40 MB, it is not "much" yet, it is a normal amount for an array of references of such a big length. But if it is several times more than that, that would be a totally different question. – Malcolm Sep 15 '10 at 15:17
  • The real question is not "is it too big" but rather "does it serve a useful purpose doing what it does", in terms of achieving some program functionality that you could not do with such a big array? In general, I doubt the utility of such a big array, especially of pointers to objects. – Ira Baxter Sep 15 '10 at 15:58
  • How much memory do you expect an array of size 10 million to take? -1 for not using your brain. – Erick Robertson Aug 11 '11 at 12:35
  • I totally agree with you Erick – Manuel Selva Aug 11 '11 at 13:57
  • 2
    But you can say it in more diplomatic way next time ;-) – Manuel Selva Aug 11 '11 at 14:49

10 Answers10

22

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
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Broken link...is there another? – Paul Draper Oct 09 '13 at 21:09
  • I found a working link: [Java HotSpot™ Virtual Machine Performance Enhancements](http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html) –  Aug 07 '14 at 15:20
18

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.

Nikita Rybak
  • 67,365
  • 22
  • 157
  • 181
Alex Reitbort
  • 13,504
  • 1
  • 40
  • 61
  • 2
    Yup... hello, basic math! It's taking the exact amount of memory it's supposed to. – Pete Sep 15 '10 at 15:24
3

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
  • 55,384
  • 17
  • 145
  • 179
3

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

gpeche
  • 21,974
  • 5
  • 38
  • 51
3

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
  • 21,744
  • 6
  • 51
  • 55
  • the heap space is not allocated while the objects are not created using new, isn't it ? – Manuel Selva Sep 15 '10 at 15:19
  • 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 Sep 15 '10 at 15:36
  • @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 Sep 21 '10 at 18:28
3

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
  • 93,541
  • 22
  • 172
  • 341
3

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

Community
  • 1
  • 1
Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
2

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
  • 190
  • 1
  • 8
2

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
  • 51,409
  • 25
  • 133
  • 214
0

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?

  • 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 Sep 15 '10 at 18:16
  • A good discussion on object memory in Java (agrees with your assesment, Yanick) http://www.javaspecialists.eu/archive/Issue029.html – Jerry Carter Sep 16 '10 at 15:45
  • 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 Sep 21 '10 at 18:30