pie*_*tom 5 java memory arrays pointers memory-consumption
我想知道在内存中为对象分配的真实空间.
我尝试用一些例子来解释:使用64位JVM,指针大小应该是8个字节,所以:
Object singletest = new Object(); 将占用8个字节来引用Object加上Object的大小Object arraytest = new Object[10]; 将需要8个字节来引用存储数组的位置加上8*10个字节来存储数组加上每个Object的大小int singleint = new int; 将只占用2个字节,因为int是基本类型int[] arrayint = new int[10]; 将占用8个字节来引用位置,并将10*2个字节用于元素而且,这就是Java允许编写这样的代码的原因:
int[][] doublearray = new int[2][];
int[0][] = new int[5];
int[1][] = new int[10];
Run Code Online (Sandbox Code Playgroud)
真正发生的是一个数组会产生一个像对象一样的引用(也就是指针),因此在声明时它并不重要第二维的大小(维度可能不同,它们之间没有链接).然后所采用的空间将是:对doublearray(8字节)的引用,第一维只是对第二维的引用,所以其他8字节*2(第一维尺寸),最后2字节*5加2字节*10 .
所以,最后,如果有这样一个真正的类:
class Test {
int a, b;
int getA() {return A};
void setA(int a) {this.a = a;}
int getB() {return B};
void setB(int b) {this.b = b;}
}
Run Code Online (Sandbox Code Playgroud)
当我调用new来实例化时,将使用8字节的指针(或它引用的名称,因为它是Java)加上2 + 2bytes来将整数存储到类中.
问题是:我是对的,还是我写完废话?此外,当我没有实例化一个对象但我只是声明它时,将分配8个字节以供进一步使用?如果我指定一个空值怎么办?
同时对于原始类型我很确定只是声明它将分配所请求的空间(如果我声明一个"int i"然后我可以立即调用i ++因为没有使用引用,只有一部分内存被设置为"0" ).
我没有聪明的回答在互联网上搜索...我知道我写了很多问题,但任何帮助将不胜感激!(也许我不是唯一感兴趣的人)
使用64位JVM,指针大小应为8个字节,
实际上它通常是32位,除非你的最大堆大小为32 GB或更多堆.这是因为Java使用引用而不是指针(并且每个对象都在8字节,而不是1个边界)
JVM可以根据您使用的JVM以及最大堆大小来更改引用的大小.
Object singletest = new Object(); 将占用8个字节来引用Object加上Object的大小
该对象将使用大约16个字节的堆.它可能会也可能不会使用4个字节的堆栈,但它可能只使用一个寄存器.
Object arraytest = new Object [10];
这将为标头使用大约16个字节,加上参考大小的10倍(总共大约56个字节)
int singleint = new int; 将只占用2个字节,因为int是基本类型
int总是32位,你不能创建一个new原语.从理论上来说,它可能使用4字节的堆栈,也可能只使用寄存器.
int [] arrayint = new int [10]; 将占用8个字节来引用位置,并将10*2个字节用于元素
同样,该对象可能与new Object[10](56字节)的大小相同
int[][] doublearray = new int[2][];
int[0][] = new int[5];
int[1][] = new int[10];
Run Code Online (Sandbox Code Playgroud)
我不会把它称为双重阵列,因为它可能会混淆 double[]
然而,尺寸可能是大约16 + 2*4 doublearray和16 + 5*4 + 4(用于填充)和16 + 10*4.
堆上分配的内存与8字节边界对齐.
我调用new来实例化,将使用8字节的指针(或引用它的名称,因为它是Java)加上2 + 2bytes来将整数存储到类中.
引用位于堆栈上,通常不包括在内.
该对象具有大约16个字节的头,并且int值占用2*4个字节.
当我没有实例化一个对象,但我只是声明它
Java不允许您声明对象,只声明基元和引用.
如果我指定一个空值怎么办?
这可能会改变引用的值,但是没有任何反应.
如果我声明一个"int i"然后我可以立即调用i ++,因为没有使用引用,只有一部分内存被设置为"0"
不会使用堆,可能不会使用堆栈(可能是4个字节).如果代码不执行任何操作,JIT编译器将删除代码.
也许我不是唯一感兴趣的人
......但是并不害怕问.;)