Java 分配给对象[]中元素的内存量
考虑以下情况Java 分配给对象[]中元素的内存量,java,arrays,memory-management,Java,Arrays,Memory Management,考虑以下情况 int[] anArray = new int[10]; 为堆上每个32位的10个元素分配内存。对吗 那么,如果元素类型是Object,那么元素的大小是多少 像 堆上现在分配了多少内存?我只是通过使用ArrayList的源代码而得到了怀疑 private transient Object[] elementData; 刚在我的机器上试过这条线 List<String> s = new ArrayList<String>(Integer.MAX_VA
int[] anArray = new int[10];
为堆上每个32位的10个元素分配内存。对吗
那么,如果元素类型是Object,那么元素的大小是多少
像
堆上现在分配了多少内存?我只是通过使用ArrayList
的源代码而得到了怀疑
private transient Object[] elementData;
刚在我的机器上试过这条线
List<String> s = new ArrayList<String>(Integer.MAX_VALUE);
List s=new ArrayList(Integer.MAX_值);
结果
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at java.util.ArrayList.<init>(Unknown Source)
at com.nextenders.server.guice.actions.servlets.Test.main(Test.java:13)
线程“main”java.lang.OutOfMemoryError中出现异常:请求的数组大小超过VM限制
位于java.util.ArrayList。(未知源)
位于com.nextenders.server.guice.actions.servlets.Test.main(Test.java:13)
所以我想知道分配了多少内存
那么,如果元素类型是Object,那么元素的大小是多少
对象[]
数组元素的大小是引用的大小
- 在32位JVM上,引用是32位(4字节)
- 在64位JVM上,引用是64位(8字节),如果启用了“压缩oop”优化且堆大小小于32Gb,则引用是32位
List s=new ArrayList(Integer.MAX_值);
在封面下,您试图分配一个包含233到234字节的数组。对于32位JVM,这保证不起作用。对于64位JVM,需要至少8Gb(压缩oop)或16Gb的堆才能工作
它将创建一个包含10个32位对象引用(存储对象的内存地址)的数组,因为java中的所有对象都只是指向存储对象的内存的指针。或者,如果您使用的是64位机器,则地址将为64位可能的重复。另请参见允许我从@Duncan链接问题中提取(并稍微调整)相关片段:
New Object[10]仅为10个对象引用创建空间。它不会创建10个对象对象(甚至10个对象对象的可用空间)
和每个引用都将是一个地址:32位CPU上32位,64位CPU上64位
是,请参阅行或10个整数对象的可用空间
。那么为什么只为初始化而发生OutOfMemoryError
,因为ArrayList(Integer.MAX_值)
请求了2^(31-1)个地址。奇怪的是,我对Oracle的解决方案感到好奇:表示应用程序[…]试图分配一个大于堆大小的数组
@MarkoTopolnik-我明白了。@StephenC 12字节的对象头开销,内存对齐导致16字节。@Eugene-这取决于JVM实现。这就是为什么我说大约12个字节。@StephenC确实如此。在JVM7更新51上,它是16字节,刚刚测试过。实际上,由于这种内存对齐,我们可以使用压缩oop,因为最后3位总是空闲的。
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
at java.util.ArrayList.<init>(Unknown Source)
at com.nextenders.server.guice.actions.servlets.Test.main(Test.java:13)
List<String> s = new ArrayList<String>(Integer.MAX_VALUE);