我正在回顾一个算法,它保持一个整数数组,输入的大小是动态的。所以根据我的计算
integer MAX_VALUE * int size = ? 2^31 integers * 4 bytes = ? 2147483648 integers * 4 bytes = 8 Gigabytes
这个计算正确吗?jvm会使用如此多的连续空间来存储int数组,还是需要考虑其他事情?
vpfxa7rd1#
不,你的最大值不正确。在java中,数组中元素的数量限制比 Integer.MAX_VALUE (2147483647),这取决于java的版本、主机操作系统以及java的编译方式。请看ivan mamontov对这个问题的回答,为什么我不能创建一个大尺寸的数组?。
Integer.MAX_VALUE
所以最大数组的大小 int 大概是 ( Integer.MAX_VALUE - 8L ) * 32L 位是68719476448位是8589934556八位字节。所以是的,大约8吉格的内存。记住:这是数组的连续内存。所以:jvm和主机操作系统可能需要做大量的工作来生成这样一个数组,这取决于运行时内存的碎片化程度。如果主机硬件没有足够的实际内存,您将进入虚拟内存,由此产生的分页可能会导致糟糕的性能。如果你真的在工作中突破了这些限制,就要经常进行真实世界的测试。您可能需要考虑为超大内存设计的java的替代实现,例如azul系统的zing。
int
( Integer.MAX_VALUE - 8L ) * 32L
w1jd8yoj2#
阵列的理论尺寸为:numberofelementsinthearray*4字节12字节头( int[] 是一个对象)。实际上,头的大小取决于您使用的标志和您运行的jvm版本4字节以保持 length 数组的衬垫。例如:(我要用jol来表示这个):
int[]
length
int [] x = new int[10]; for(int i=0;i<10;++i){ x[i] = 9999; } System.out.println(GraphLayout.parseInstance((Object)x).toPrintable());
将输出:
[I@7a81197dd object externals: ADDRESS SIZE TYPE PATH VALUE 70fe45268 56 [I [9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999]
是的 56 bytes :值本身为40(10英寸*4字节)12用于收割台长度为40用于填充如果将此数组更改为 Integer ,事情发生了巨大的变化。 Integer 是一个对象,因此您将在数组中存储一个引用(可以是 4 或者 8 字节,取决于 UseCompressedOops 标志),加上 Integer 示例将需要2个标头(每个 Integer 是一个对象)。
56 bytes
Integer
4
8
UseCompressedOops
Integer[] y = new Integer[10]; for(int i=0;i<10;++i){ y[i] = 9999; } System.out.println(GraphLayout.parseInstance((Object)y).toFootprint());
将显示:
[Ljava.lang.Integer;@369f73a2d footprint: COUNT AVG SUM DESCRIPTION 1 56 56 [Ljava.lang.Integer; 10 16 160 java.lang.Integer 11 216 (total)
总共 216 bytes :每个引用4字节(我有 UseCompressedOop 打开),总共40字节数组的12字节头数组的4字节长度0字节填充该数组中的每个引用都指向一个 Integer ,每个对象都将具有 16 bytes :内部4字节 int 他们坚持住了12字节头0字节填充
216 bytes
UseCompressedOop
16 bytes
2条答案
按热度按时间vpfxa7rd1#
数组大小最大值<integer.max\u值
不,你的最大值不正确。
在java中,数组中元素的数量限制比
Integer.MAX_VALUE
(2147483647),这取决于java的版本、主机操作系统以及java的编译方式。请看ivan mamontov对这个问题的回答,为什么我不能创建一个大尺寸的数组?。是的,int的最大数组≈ 8场演出
所以最大数组的大小
int
大概是( Integer.MAX_VALUE - 8L ) * 32L
位是68719476448位是8589934556八位字节。所以是的,大约8吉格的内存。记住:这是数组的连续内存。所以:
jvm和主机操作系统可能需要做大量的工作来生成这样一个数组,这取决于运行时内存的碎片化程度。
如果主机硬件没有足够的实际内存,您将进入虚拟内存,由此产生的分页可能会导致糟糕的性能。
如果你真的在工作中突破了这些限制,就要经常进行真实世界的测试。您可能需要考虑为超大内存设计的java的替代实现,例如azul系统的zing。
w1jd8yoj2#
阵列的理论尺寸为:
numberofelementsinthearray*4字节
12字节头(
int[]
是一个对象)。实际上,头的大小取决于您使用的标志和您运行的jvm版本4字节以保持
length
数组的衬垫。
例如:(我要用jol来表示这个):
将输出:
是的
56 bytes
:值本身为40(10英寸*4字节)
12用于收割台
长度为4
0用于填充
如果将此数组更改为
Integer
,事情发生了巨大的变化。Integer
是一个对象,因此您将在数组中存储一个引用(可以是4
或者8
字节,取决于UseCompressedOops
标志),加上Integer
示例将需要2个标头(每个Integer
是一个对象)。将显示:
总共
216 bytes
:每个引用4字节(我有
UseCompressedOop
打开),总共40字节数组的12字节头
数组的4字节长度
0字节填充
该数组中的每个引用都指向一个
Integer
,每个对象都将具有16 bytes
:内部4字节
int
他们坚持住了12字节头
0字节填充