简体   繁体   English

为什么创建一个大型Java阵列会消耗如此多的内存?

[英]Why does creating a big Java array consume so much memory?

Why does the following line 为什么以下行

    Object[] objects = new Object[10000000];

result in a lot of memory (~40M) being used by the JVM? 导致JVM使用大量内存(~40M)? Is there any way to know the internal workings of the VM when allocating arrays? 有什么方法可以在分配数组时了解VM的内部工作原理吗?

Well, that allocates enough space for 10000000 references, as well as a small amount of overhead for the array object itself. 好吧,它为10000000个引用分配了足够的空间,以及数组对象本身的少量开销。

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. 实际大小将取决于VM - 但它占用相当大的内存肯定不足为奇......我希望64位VM上至少有 40MB,可能是80MB,除非它使用压缩oops阵列。

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. 当然,如果使用那么多不同的对象填充数组,那将需要更多,更多的内存......但是数组本身仍然只需要空间用于引用。

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. 你分配10000000个指针,每个指针占用4个字节(在32位机器上) - 这大约是40mb的内存。

You are creating ten million references to an object. 您正在创建一千万个对象的引用。 A reference is at least 4 bytes; 引用至少为4个字节; IIRC in Java it might be 8, but I'm unsure of that. Java中的IIRC可能是8,但我不确定。

So with that one line you're creating 40 or 80 megabytes of data. 因此,使用这一行,您将创建40或80兆字节的数据。

You are reserving space for ten million references. 您正在为一千万个参考预留空间。 That is quite a bit. 那是相当多的。

It results in a lot of memory being used because it needs to allocate heap space for 10 million objects and their associated overhead. 它导致使用大量内存,因为它需要为1000万个对象分配堆空间及其相关的开销。

To look into the internal workings of the JVM, you can check out its source code , as it is open source. 要查看JVM的内部工作原理,您可以查看其源代码 ,因为它是开源的。

Your array has to hold 10 million object references, which on modern platforms are 64 bit (8 byte) pointers. 你的数组必须容纳1000万个对象引用,在现代平台上是64位(8字节)指针。 Since it is allocated as a contiguous chunk of storage, it should take 80 million bytes. 由于它被分配为一个连续的存储块,因此它应该占用8000万字节。 That's big in one sense, small compared to the likely amount of memory you have. 从某种意义上讲,这是很大的,与你可能拥有的内存量相比很小。 Why does it bother you? 为什么打扰你?

It creates an array with 10.000.000 reference pointers, all initialized with null . 它创建一个包含10.000.000个引用指针的数组,所有引用都用null初始化。

What did you expect, saying this is "a lot"? 你有什么期望,说这是“很多”?


Further reading 进一步阅读

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. 这意味着访问[i]所花费的时间对于每个索引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. 这是因为可以通过向阵列头部的地址添加合适的偏移来算术地确定a [i]的地址。 The reason is that space for the contents of an array is allocated as a contiguous block of memory. 原因是数组内容的空间被分配为连续的内存块。

According to this site, the memory usage for arrays is a 12 bytes header + 4 bytes per element. 根据站点,数组的内存使用量是12个字节的头部+每个元素4个字节。 If you declare an empty array of Object holding 10M elements, then you have just about 40MB of memory used from the start. 如果你声明的空数组Object持有10M的元素,那么你只是从一开始就使用了40MB内存。 If you start filling that array with actually 10M object, then the size increases quite rapidly. 如果你开始用实际的10M对象填充该数组,那么大小会非常快速地增加。

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) 这个站点,我刚刚在我的64位机器上测试它,一个普通Object的大小大约是31个字节,所以一个10M的Object数组大约是12个字节+(4 + 31个字节)* 10M = 350 000 012字节(或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. 甚至可以使用Apache Derby等数据库,它还可以让您对数据进行排序和过滤等。

I may be behind the times but I understood from the book Practical Java that Vectors are more efficient and faster than Arrays. 我可能落后于时代,但我从实用Java这本书中了解到,矢量比阵列更有效,更快。 Is it possible to use a Vector instead of an array? 是否可以使用Vector而不是数组?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM