我对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中的内存问题吗?
答案 0 :(得分:2)
i
后, Integer
会自动装箱到getObjectSize
。
因此,您获得提升变量的大小值,不原始基元int
。
要规避此行为,请为原始案例构建getObjectSize
的重载:
public static long getObjectSize(int o) {
return Integer.SIZE / 8;
}
等等。
答案 1 :(得分:2)
int
是一种基本类型,大小为4个字节,Integer
是引用类型,其大小为16个字节。在这种情况下,为什么它会为这两个值重新调整16个字节?
因为ObjectSizeFetcher.getObjectSize(Object)
来电是int
自动装箱Integer
。
AFAIK,没有标准的API来衡量基本类型或引用的大小。一个原因是尺寸将取决于它的存储位置和方式。例如,存储在(大)byte[]
中的字节很可能比存储为对象字段的字节占用更少的空间。并且byte
持有的局部变量可能会再次不同。 (包装和校准有问题,以解决问题。)
编写重载方法以返回每种基本类型的常量最小大小很简单。引用有点棘手,因为引用的大小取决于您使用的是32位还是64位JVM,以及是否启用了压缩oops。