为什么创建一个大的Java数组会消耗这么多内存?

为什么创建一个大的Java数组会消耗这么多内存?,java,arrays,memory,Java,Arrays,Memory,为什么下面这行 Object[] objects = new Object[10000000]; 导致JVM使用大量内存(~40M)?在分配数组时,有没有办法知道VM的内部工作情况?好的,它为10000000个引用分配了足够的空间,并且为数组对象本身分配了少量开销 实际大小将取决于虚拟机-但它占用相当多的内存肯定并不奇怪。。。我希望至少40MB,在64位虚拟机上可能80MB,除非它用于阵列 当然,如果你用那么多不同的对象填充数组,那会占用更多的内存。。。但是数组本身仍然需要空间来进行引

为什么下面这行

    Object[] objects = new Object[10000000];

导致JVM使用大量内存(~40M)?在分配数组时,有没有办法知道VM的内部工作情况?

好的,它为10000000个引用分配了足够的空间,并且为数组对象本身分配了少量开销

实际大小将取决于虚拟机-但它占用相当多的内存肯定并不奇怪。。。我希望至少40MB,在64位虚拟机上可能80MB,除非它用于阵列


当然,如果你用那么多不同的对象填充数组,那会占用更多的内存。。。但是数组本身仍然需要空间来进行引用。

数组被广泛使用的主要原因之一是它们的元素可以在固定的时间内访问。这意味着对于每个索引i,访问a[i]所花费的时间是相同的。这是因为[i]的地址可以通过向数组头的地址添加合适的偏移量来算术确定原因是数组内容的空间被分配为连续的内存块。

您正在创建一个对象的1000万个引用。引用至少为4个字节;Java中的IIRC可能是8,但我不确定


因此,通过这一行,您可以创建40或80兆字节的数据

您正在为一千万个引用保留空间。这是相当大的一部分。

它会导致大量内存被使用,因为它需要为1000万个对象及其相关开销分配堆空间


要查看JVM的内部工作,您可以,因为它是开源的。

您的数组必须包含1000万个对象引用,在现代平台上,这些引用是64位(8字节)指针。由于它是作为一个连续的存储块分配的,所以需要8000万字节。从某种意义上说,这是很大的,与你可能拥有的记忆量相比,这是很小的。为什么它会困扰你?

你说的“大量内存”是什么意思?分配10000000个指针,每个指针占用4个字节(在32位机器上)-这大约是40mb内存。

它创建了一个包含10.000.000个参考指针的数组,所有指针都用
null
初始化

你以为这是“很多”吗


进一步阅读

根据站点的说法,阵列的内存使用量是12字节头+每个元素4字节。如果您声明一个包含10M个元素的
Object
空数组,那么从一开始就只使用了大约40MB的内存。如果你开始用10米的物体填充这个数组,那么它的大小会迅速增加

我刚刚在我的64位机器上测试了它,一个普通的
对象的大小大约是31字节,所以一个10M的
对象的数组大约是12字节+(4+31字节)*10M=350000012字节(或345.78MB)

如果阵列包含其他类型的对象,则大小将更大


我建议您使用某种随机访问文件来保存数据,如果您必须在程序中保存这么多数据的话。甚至可以使用数据库,例如,它还可以让您对数据进行排序和筛选等。

我可能落后于时代,但我从《实用Java》一书中了解到,向量比数组更高效、更快。可以用向量代替数组吗?

多少内存?“你预计消费多少?”马尔科姆:问得好。现在,我们不认为40MB是那么大的内存,是吗?然而,回到今天……答案中刚刚提到,如果它是40MB,它还不算“太多”,对于一个如此长的引用数组来说,这是一个正常的数量。但是,如果它是这个数的几倍以上,那将是一个完全不同的问题。真正的问题不是“它太大了吗”,而是“做它所做的事情是否有用”,在实现一些程序功能方面,你不能用这么大的数组来实现?总的来说,我怀疑这么大的数组,尤其是指向对象的指针是否有用。但下次你可以用更圆滑的方式来说;-)当对象不是使用new创建时,堆空间没有被分配,不是吗?这是一种看待它的一般方式,因为要创建对象,您使用
new
,然后它进入堆。但更具体地说:堆包含对象及其实例变量(包括不是用
new
创建的原语)。数组值也在堆上。@曼努埃尔·塞尔瓦:是的,数组中包含的对象的堆空间仅在创建对象时分配。但是,数组本身也需要空间来容纳对象引用,如其他答案中所述。数组的空间会立即分配,即使它只包含空值。。。你好,基础数学!它占用了它应该占用的内存量。为什么是“4*31”而不是“4+31”?哎呀,是的,修好了。谢谢:)使用向量并不会使它在资源方面变得更小。事实上,它甚至可能是最糟糕的,因为一个向量在内部使用一个数组,并且数组的大小随着插入更多的项而改变+1个元素:)非常有趣-我不知道这一点。谢谢关于Java中对象内存的一个很好的讨论(同意你的评估,Yanick)你不能说向量总是更有效——这取决于它们的使用方式。向量(更好:列表-使用界面)更容易使用(可调整大小,可以在任何地方插入等),因此它们通常是首选。断开的链接…还有其他链接吗?我发现了一个工作链接: