我试图在使用数组时围绕原始内存在不同语言中的样子.
请考虑以下Java代码:
String a = "hi";
String b = "there";
String c = "everyone";
String[] array = {a, b, c};
Run Code Online (Sandbox Code Playgroud)
显然数组是持有引用,而不是对象; 也就是说,在三个引用的内存中存在一个连续的数组,每个引用指向对象所在的内存中的某个其他位置.因此,物体本身不一定坐在三个连续的桶中; 而参考文献是.
现在考虑一下:
String[] array = {"hi", "there", "everyone"}
Run Code Online (Sandbox Code Playgroud)
我想在这种情况下,字符串存在于内存中的所有其他常量,然后数组保存对内存中这些常量的引用?因此,在原始内存中,数组看起来并不像['h', 'i', '\0', 't', 'h', 'e', 'r', 'e'... (etc)].(为方便起见,使用c风格的终止).相反,它更像['a83a3edf' ,'a38decd' ... (etc)]是每个元素都是内存位置(引用).
我从这个思考过程中得出的结论是,在Java中,你永远不能将数组想象成内存中连续对象的桶,而是连续的引用.我想不出有什么方法可以保证对象总是在Java中连续存储.
现在考虑C:
char *a = "hi";
char *b = "there";
char *c = "everyone";
char *array[] = {a, b, c};
Run Code Online (Sandbox Code Playgroud)
上面的代码在功能上等同于上面的Java - 也就是说,数组保存对其他内存位置的引用(指针).与Java一样,指向的对象不一定是连续的.
但是,在以下C代码中:
struct my_struct array[5]; // allocates 5 * size(my_struct) in memory! NOT room for 5
// references/pointers, but room for 5 my_structs.
Run Code Online (Sandbox Code Playgroud)
arrayARE中的结构连续位于原始内存中.
现在我的具体问题:
我是否正确地假设在Java中,数组必须始终保持引用,因为程序员只能访问Java中的引用?原始数据类型怎么样?它会以不同的方式工作吗?intJava中的一个数组看起来就像原始内存中的C一样(除了ObjectJava类将添加的类)?
在Java中,程序员是否无法保证对象的连续内存分配?它可能偶然发生,或者概率很高,但程序员不能保证会这样吗?
在C中,程序员可以在内存中连续创建对象(结构)的原始数组,如上所示,对吗?
其他语言如何处理这个问题?我猜Python就像Java一样?
这个问题的动机是我希望通过这些语言中的数组能够充分了解原始内存级别的情况.主要是程序员面试问题.我在之前的一次采访中说过,一个数组(不是任何语言,一般而言)都会像桶一样在内存中连续存放对象.只有在我说完之后,才意识到它并不像Java这样的语言.所以我想100%清楚它.
谢谢.如果有任何需要澄清,请告诉我.
你永远不能把数组想象成内存中连续对象的桶,而是连续的引用.
从理论上讲,你是对的,在实践中,JVM不会随机化内存访问.它按顺序分配内存,并按照发现顺序(或逆序)在GC期间复制对象
我是否正确地假设在Java中,数组必须始终保持引用,因为程序员只能访问Java中的引用?
是的,除非你当然有一系列基元.
原始数据类型怎么样?它会以不同的方式工作吗?
基元和参考在记忆中是连续的.它们基本相同.
Java中的一组int将看起来就像原始内存中的C一样(除了Object类cruft Java将添加)?
是.
在Java中,程序员是否无法保证对象的连续内存分配?
除非您使用堆内存,否则不会.虽然通常这不像大多数时候你想象的那么多,但是对象在内存中会是连续的.
它可能偶然发生,或者概率很高,但程序员不能保证会这样吗?
正确.通常,当您查看最差的0.1%延迟或更高时,您会遇到更大的问题.
在C中,程序员可以在内存中连续创建对象(结构)的原始数组,如上所示,对吗?
是.您也可以在Java中执行此操作,但必须使用off堆内存.有许多库支持这一点,如Javolution,Chronicle,SBE.