Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以查询Java虚拟机以找到可能的最大数组大小?怎么用?_Java_Arrays_Virtual Machine - Fatal编程技术网

是否可以查询Java虚拟机以找到可能的最大数组大小?怎么用?

是否可以查询Java虚拟机以找到可能的最大数组大小?怎么用?,java,arrays,virtual-machine,Java,Arrays,Virtual Machine,我有一个程序,我想在其中分配尽可能大的数组。在Java中有没有一种方法可以查询VM来找出它是什么?如果是,我怎么做 我最近一次获取信息的尝试是反复尝试:我开始尝试使用size Integer.MAX_值分配数组,并不断将大小减1,直到分配成功。但是,这需要很长时间;显然,实际最大值远未接近理论极限。我确定它至少是Integer.MAX_值+1。仔细想想,它至少有12.5亿字节。最大理论数组大小是整数。MAX_值(因为内部VM结构保持int中的长度),但Hotspot至少有一点不允许数组大于整数。

我有一个程序,我想在其中分配尽可能大的数组。在Java中有没有一种方法可以查询VM来找出它是什么?如果是,我怎么做


我最近一次获取信息的尝试是反复尝试:我开始尝试使用size Integer.MAX_值分配数组,并不断将大小减1,直到分配成功。但是,这需要很长时间;显然,实际最大值远未接近理论极限。我确定它至少是Integer.MAX_值+1。仔细想想,它至少有12.5亿字节。

最大理论数组大小是
整数。MAX_值
(因为内部VM结构保持
int
中的长度),但Hotspot至少有一点不允许数组大于
整数。MAX_值-5

然而,这仍然是一个很大的记忆。当然,很难想象一个合理的程序会“尽我所能”分配一个数组,因为这将开始对性能有害。GC喜欢四处移动东西,它针对对象而不是大块内存进行了调整

当然,您可以检查可用内存(使用
Runtime.freemory()
等)并基于此进行分配,但我敢打赌,无论您试图解决什么问题,都可以用更好的方式来完成

另见


当然,
MAX-5
是用于热点的。其他虚拟机可以支持其他功能,但可能不会有太大区别。

java.util.ArrayList
中,最大数组大小定义为
Integer.MAX\u VALUE-8
(从Oracle JDK 8开始):


这并不优雅,但我已经找到了一种获取所需信息的方法。我在上面提到了一个顺序搜索,我试图找到最大的字节数组;太慢了。我将它切换为二进制搜索,现在它大约在7秒钟内完成。不是很优雅,需要花费大量的时间,但它足够快,而且可以工作。下面是执行此任务的代码片段:

int can=0,tant=Integer.MAX\u值;
做{
int middle=(int)((can+(long)cant)/2);//long是为了避免总和溢出
分配=假;
试一试{
byteArray=新字节[中间];
分配=真;
}
catch(java.lang.OutOfMemorye错误){
byteArray=null;
}//抓住
System.out.printf(“正在尝试分配%,d字节,\n”,中间);
如果(已分配)
can=中间;
其他的
铁路超高=中间;
}而(铁路超高-can>1);
if(!allocated)//如果middle在上面的最后一次迭代中分配失败,则会发生这种情况
byteArray=新字节[can];

在我的系统上,我只能分配1386916521字节。

运行时类有一些方法,您可能会发现这些方法很有用……尝试根据您提供的内存量来计算应该有多少
int
s空间,JVM总是会给您错误的内存量。JVM本身使用相当大的内存来初始化所有内容。如果您分析一个只有
while(true)
循环的应用程序,您可以看到有超过1.5k个类被加载,只是为了让它运行为什么要创建这么大的数组?ArrayList并不比一个数组慢多少,它会增长以满足您的需要。更多信息:wrt。实际与理论数量:要增加实际限制,还需将JVM的最大堆调整
-Xmx16G
。另外,
byte[]array
显然比
double[]array
占用的空间要少,实际上要少8倍。这个程序是我试图看看我能找到多少素数,速度有多快。该数组用作位数组,每个字节存储8个布尔值;每个布尔值表示奇数是否为素数。我用一个100亿比特的数组来运行它。因为它大于Integer.MAX_值,所以它是用long而不是int来索引的。这可能需要更高级的方法,使用多个数组。对于额外的速度(数组访问进行边界检查),
Unsafe
类可以让您直接更快地访问数组。令人惊讶的是,速度目前不是问题;程序会在几分钟内找到所有高达100亿的素数。我不熟悉不安全类,也没有在文档中看到它。它不是通用的(虽然我认为它计划在Java 9中使用),但是当您确实需要速度并且愿意经历一些技巧时,它可以用于在某些情况下提高性能。有些人在速度至关重要的时候使用它。无论如何,一个包含多个大数组的类可以用来提供一个大的“伪数组”。我来试试,但我的程序应该很快就知道它是否接近Integer.MAX_值。您是否意识到查找最大数组大小的过程在减少可分配的数组大小的过程中使用了内存?是的,但它应该被垃圾收集,因为我没有保留对它的任何引用。但这是一个有趣的想法;也许我应该在每次成功分配后显式调用gc(),但在Java中不可能显式调用gc。您所能做的就是向gc指出,您希望在某个时候使用System.gc()创建一个集合@但情况不是总是这样吗?
/**
 * The maximum size of array to allocate.
 * Some VMs reserve some header words in an array.
 * Attempts to allocate larger arrays may result in
 * OutOfMemoryError: Requested array size exceeds VM limit
 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;