Java 最大的阵列需要多少内存?
我想获得在Java中创建尽可能大的数组所需的确切内存量 我的测试计划:Java 最大的阵列需要多少内存?,java,arrays,memory,Java,Arrays,Memory,我想获得在Java中创建尽可能大的数组所需的确切内存量 我的测试计划: public class MemoryOfArraysTest { public static void main(String... args) { Object[] array = new Object[Integer.MAX_VALUE - 2]; } } 通过自己的测试,我知道数组的最大长度是Integer.MAX_VALUE-2(2147483645) 如果该数字较大,则会出现以下
public class MemoryOfArraysTest {
public static void main(String... args) {
Object[] array = new Object[Integer.MAX_VALUE - 2];
}
}
通过自己的测试,我知道数组的最大长度是Integer.MAX_VALUE-2
(2147483645)
如果该数字较大,则会出现以下错误:
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at MemoryOfArraysTest.main(MemoryOfArraysTest.java:3)
但这只是接近阵列最大长度的一步。另一个问题是虚拟机可以使用的内存。您可以使用指定内存
如果我使用java-Xmx1g MemoryOfArraysTest
(只有1GB内存)运行我的类,我会得到预期的错误:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at MemoryOfArraysTest.main(MemoryOfArraysTest.java:3)
如果我使用java-Xmx10g MemoryOfArraysTest
(10GB内存)运行它,它就可以正常工作
这就是我目前所拥有的。但是我的程序需要多少内存呢?最好是KB的。有没有可能计算它的方法?每个对象有两个头,使用
XX:+UseCompressedOops
(默认为启用),这两个头将有12个字节。加上4个字节
,以保持数组的长度。再加上一些你需要考虑的最终填充
你可以用它来了解它有多大。这样的实验:
Object[] array = new Object[100];
for(int i=0;i<100;++i){
array[i] = new Object();
}
System.out.println(GraphLayout.parseInstance(array).totalSize());
这是一个非常酷的概念,但是为什么?Integer.MAX_VALUE-2==2147483646个元素。在具有-XX:+UseCompressedOops
(默认值)的64位VM上,引用需要4个字节。OpenJDK上当前的数组头占用16个字节(注意,Zing和OpenJ9可能不同,project最终会出现),因此2147483646*4+16个字节。但是为什么呢?很少需要知道这一点。你在解决什么问题,你想达到什么目的?事实上不可能找到答案。至少,这是不可行的。您无法知道类加载器加载的其他类占用了多少堆空间(例如,所有java.lang垃圾)。如果不知道这一点,你就不知道还有多少堆留给你。默认情况下加载的内容所使用的堆的确切数量在JDK的几乎每个构建版本之间都会略有不同。旁注:最大可能的数组是long[]
或double[]
,因为每个条目将占用64
位或8
字节。使用可能的最大数组大小(Integer.MAX_VALUE=2^31-1
)进行计算会产生略大于16
GB(17179869192
字节)的大小,因为它没有真正的用例。我不想创建这样一个长度的数组。我只是好奇什么是等式,以及Java中通常如何管理数组。但我认为这样问不会得到回答。因为我的问题不是很清楚。感谢所有的评论和答案。它们有助于我更好地理解内存的主题。我的mac上有32GB
的RAM,即使我尝试增加交换,我的mac在尝试计算该大小的填充数组时也会关闭
Object[] array = new Object[Integer.MAX_VALUE - 2];
System.out.println(ClassLayout.parseInstance(array).instanceSize());