我对Java中的int和Integer变量的内存分配有疑问。为了测量内存,我使用了Instrumentation.getObjectSize(),它为两个变量产生了相同的大小。请在下面找到我的代码:
ObjectSizeFetcher.java
import java.lang.instrument.Instrumentation;
public class ObjectSizeFetcher {
private static Instrumentation instrumentation;
public static void premain(String args, Instrumentation inst) {
instrumentation = inst;
}
public static long getObjectSize(Object o) {
return instrumentation.getObjectSize(o);
}
}
Test.java
public class Test {
public static void main(String[] args) throws Exception {
int i=0;
Integer i1 = new Integer(0);
long value = ObjectSizeFetcher.getObjectSize(i);
System.out.println(value);//prints 16
long value1 = ObjectSizeFetcher.getObjectSize(i1);
System.out.println(value1);//prints 16
}
}
在上述情况下,两个变量大小都打印相同。我的疑问是,int是原始类型,其大小为4个字节,Integer是引用类型,其大小为16个字节,但是在这种情况下,为什么两个值都产生16个字节?如果两者在堆中占用的内存量相同,则将导致Java中的内存问题对吗?
i传递给getObjectSize时将自动装箱到Integer。
因此您将获得提升变量大小的值,而不是原始图元int的值。 >
要避免此行为,请针对以下原始情况构建getObjectSize的重载:
public static long getObjectSize(int o) {
return Integer.SIZE / 8;
}
,依此类推。
int is a primitive type and it size 4 bytes and Integer is reference type and its size is 16 bytes. In this case, why does it retuyrn 16 bytes for both the values?
由于ObjectSizeFetcher.getObjectSize(Object)调用会将int自动装箱到Integer。
AFAIK,因此没有标准的API可以测量基本类型或引用的大小。原因之一是大小取决于存储位置/存储方式。例如,存储在(大)byte[]中的字节将很可能比存储为对象字段的字节占用更少的空间。而byte是局部变量,可能会再次不同。 (存在打包和对齐的问题。)
编写重载方法以返回每种基本类型的恒定最小大小很简单。引用比较棘手,因为引用的大小取决于您使用的是32位还是64位JVM,以及是否启用压缩的oops。