java.lang.OutOfMemoryError:初始化数组时的java堆空间
我试图初始化一个布尔类型的数组,它的大小是10位整数。它不断抛出OutOfMemoryException。我已经将eclipse的堆空间大小从256增加到1024。有什么我没做的吗java.lang.OutOfMemoryError:初始化数组时的java堆空间,java,arrays,initialization,Java,Arrays,Initialization,我试图初始化一个布尔类型的数组,它的大小是10位整数。它不断抛出OutOfMemoryException。我已经将eclipse的堆空间大小从256增加到1024。有什么我没做的吗 int size = 1000000000; boolean[] primesList = new boolean[size]; 从 此数据类型表示一位信息,但其“大小”并不是精确定义的 如果考虑布尔值至少一个字节,即 1000000000 字节,则需要代码> 953Mb内存。< /P> 因此,这是唯一一个占用10
int size = 1000000000;
boolean[] primesList = new boolean[size];
从
此数据类型表示一位信息,但其“大小”并不是精确定义的
如果考虑布尔值至少一个字节,即<代码> 1000000000 字节,则需要<数组>代码> 953Mb</代码>内存。< /P> 因此,这是唯一一个占用
1024MB
中953MB
的数组,这可能是导致问题的原因
但在一个好的环境中,我想这个用例不需要:)启动JVM时,需要传递-Xmx参数以将最大堆空间设置为更高 还请注意,数组的最大大小为Integer.MAX_VALUEUse,与使用
布尔
数组相比,它将位压缩在八分之一的空间中
布尔数组元素使用1字节而不是1位的原因是(大多数)CPU体系结构不提供直接读取和写入单个内存位的能力。个人计算机能操作的最小单位是8位。JVM可以将这些位打包在一起,然后为了修改一个位,它将读取字节,修改字节,然后将其写回,但如果多个线程同时修改数组,则这不起作用
对于原始数组,它是10亿个布尔值,每个布尔值一个字节,即10亿字节或~954 MB。所以1024MB的堆应该足够了(?)。可能它找不到足够大的连续内存块,或者您没有正确设置内存参数。打印Runtime.getRuntime().maxMemory()
的值,以找出Java正在使用的最大堆大小。对于1024MB,参数应为-Xmx1024M
最后一点注意:从Java7开始,您可以在数字中使用下划线,以使其更具可读性。因此,您可以编写
1\u 000\u 000
而不是100000000
您可以使用对象持有者,避免需要一次分配所有空间-如果堆大小足够大,这可能会解决问题。在一个数组中容纳那么多布尔值需要很大的空间——请确保为堆空间设置了最小和最大大小。
也可以使用类似列表的方法,仅在需要时填充值。如果您确实需要将其转换为数组,可以通过多种方式进行转换(apache commons中的数组集合允许您使用Arrays.toPrimitive)。布尔数组存储为字节:
我认为您需要重新考虑一下您是如何做到这一点的-创建大小为GB的数据结构超出了当前硬件的能力。只需请求更多堆大小,例如-X1500M肯定可以。您的数组占用100000000字节,但您需要请求更多字节,因为Java堆分为新的+旧的几代。这可能是由于以下两个原因:
你真的需要这么大的空间吗?首先计算:大小*4字节加上其他对象。使用instead@ajozwik你从哪里得到的大小*4字节?请参阅@GarethDavis,它可能用于生成素数筛或用于任意数的素数测试,这需要一个这样的随机访问数组来提高性能。你在那里添加了一个零,布尔值不需要一位,至少在这种形式下。你计算错了。有10位数字,而不是11位。@ViktorOzerov是的,你说得对,多余的零已经被删除了。谢谢你的指点。