我想提高我对编程语言的内存模型(特别是Java)的知识,所以我有一个问题。
以下是非常简单的代码:
// Allocating memory in heap for SimpleObject's instance
// Creating reference to this object with name so1
SimpleObject so1 = new SimpleObject();
// Allocating memory in heap for array of 10 references to SimpleObject's objects
// Now I know, that array stores only references to the objects
// (Previously I thought that array stores objects)
// Then we create reference to this array with name soArray
SimpleObject[] soArray = new SimpleObject[10];
现在的问题是:
// What is going on here?
soArray[0] = so1;
// object so1 had been really moved to memory area of soArray?
// And so1 reference have been updated to new memory address?
// Or we just had assigned so1 object's reference to soArray[0] element?
// Or so1 object had been copied to the soArray[0]?
// Then original so1 object has been deleted and all links to it had been updated?
如果您知道,它如何在其他语言中工作,例如(C,C ++,C#或其他语言),请回答,我很乐意知道。
大家都知道,ArrayList可以比LinkedList快,因为数组元素可以存储在CPU缓存中,而如果我们使用LinkedList,CPU每次都必须从RAM中获取下一个对象。
那怎么可能呢,如果一开始我在堆中创建了对象,那时我就把对象放在数组中了?
UPD:谢谢各位,现在我了解数组是如何工作的,但是以这种方式缓存CPU缓存中的数组呢?答案 0 :(得分:4)
Arrays将引用存储到对象,而不是对象本身。因此,在分配0
时,您可以在位置soArray[0]
处交换参考。可以在堆中移动它们所服务的对象,但这通常是由于GC,而不是分配。
如果对象本身直接存储在数组中,则不能在数组中包含更多实例字段的子类实例。它们不适合分配的空间,因此只能成为基类的实例。当你分配存储在堆栈中的类实例时,这就是C ++中实际发生的事情。
答案 1 :(得分:2)
在Java中,数组存储对象的引用。用C ++的说法,它们存储指向对象的指针。
SimpleObject[] soArray = new SimpleObject[10]; //Java
SimpleObject* cppArray[10]; // C++ equivalent
soArray[0] = so1;
在so1
中引用soArray[0]
,与cppArray[0] = &so1
存储指向so1
的指针的方式相同。原始对象保持不变,不分配或取消分配额外的内存。
在C ++中,您可以将对象直接存储在数组中。
SimpleObject soArray[10]; // An array that stores Simple Objects in place
SimpleObject so1; // A new object
soArray[0] = so1; // This *copies* so1 into soArray[0]
答案 2 :(得分:-1)
我们将对so1指向的对象的引用赋给数组元素。
这里有一个使用Python Tutor的例子(我知道Java没有相应的工具,但内存模型类似,除了Class是一个对象,所以忽略它):< / p>