Java如何获取最大的字节数组大小以适应虚拟机限制

3

我该如何找到最大字节数组大小,以不超过VM限制?

我尝试的方法是:

int size = Integer.MAX_VALUE;
byte[] request = new byte[size];

但是我遇到了错误:Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit 背景是我的数据包代理会丢失数据包的某些部分,因为我不知道可以使用的内存大小限制。
谢谢!

仅提一下,使用大数组时会遇到各种与GC相关的问题,特别是在动态分配它们时。如果您在程序启动时创建了一些托管对象,可能是安全的。但是,像离堆ByteBuffer这样的替代方案可能会更好。 - eckes
放弃吧!!你不应该有意地尝试创建一个占用大部分可用堆的巨大数组。这样做会有太多的问题回来咬你。 - Hot Licks
1
没有有效的通信协议应该要求您分配巨大的缓冲区。 - Hot Licks
请注意,可能有许多Java实现无法创建Integer.MAX_VALUE元素的字节数组,无论堆空间有多少,因为最大对象大小最多为该值,并且对象需要至少16个,可能是32个字节的“头”。 - Hot Licks
3个回答

4

使用类似下面这样的方式,您可以自己找到问题的答案:

long maxByteArraySize() {
   long size = Integer.MAX_VALUE;
   while(--size > 0) try {
        new byte[size];
        break;
   } catch(Throwable t) {}   
   return size;
}

请注意,您可以使用-Xmx标志增加jvm可用的内存量,例如:java -Xmx4g MyClass可能会让您分配(大量)比默认值更大的数组。

(并不是我认为您尝试做的事情实际上是一个好主意...)


0

好的,Integer.MAX_VALUE2,147,483,647;你可以使用以下代码确定有多少内存可用:

System.out.println(Runtime.getRuntime().freeMemory());

但我不会尝试将所有内容分配给byte[]


0

在Java中,数组被认为是对象。而对象存储在堆内存中。无论您的对象是本地对象还是全局对象,只有它的引用存储在栈内存中。您可以通过以下方式找到最大堆大小

java -XX:+PrintFlagsFinal -version 2>&1 | findstr MaxHeapSize

大约使用较小的数组。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接