当使用数组时,我正试图了解原始内存在不同语言中的样子。
考虑以下Java代码:
String a = "hi";
String b = "there";
String c = "everyone";
String[] array = {a, b, c};
显然,数组保存的是引用,而不是对象;也就是说,内存中有一个连续的数组,每个数组都指向内存中对象所在的其他位置。因此,对象本身并不一定位于三个连续的桶中;相反,引用是。
现在考虑这一点:
String[] array = {"hi", "there", "everyone"}
我可以想象,在这种情况下,String存在于内存中所有其他常量的某个地方,然后数组保存对内存中这些常量的引用?因此,在原始内存中,数组看起来不像['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};
上面的代码在功能上相当于上面的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.
array
中的结构连续地位于原始内存中。
现在说说我的具体问题:
int
数组是否与原始内存中的C中的数组类似(除了Object
类cruft将添加)?提出这个问题的动机是,我想要对这些语言中的数组在原始内存级别上发生的事情有一个坚实的理解。主要是针对程序员的面试问题。我在前一次采访中说过,数组(不是任何语言,一般情况下)在内存中像存储桶一样连续地保存对象。直到我说了这些之后,我才意识到,在Java这样的语言中,它的工作方式并不是这样的。所以我想100%的说清楚。
谢谢。如果有什么需要澄清的话请告诉我。
发布于 2015-09-03 17:20:20
您永远无法想象数组是内存中的一桶连续对象,而是连续的引用。
从理论上讲,您是对的,在实践中,JVM不对内存访问进行随机化。它按顺序分配内存,并在GC期间按发现顺序(或反向顺序)复制对象。
我是否正确地认为,在Java中,数组必须始终保存引用,因为程序员只能访问Java中的引用吗?
是的,当然,除非您有一个原语数组。
原始数据类型呢?那会有不同的效果吗?
原语和引用在内存中是连续的。基本上是一样的。
Java中的ints数组是否与原始内存中的C中的数组类似(除了cruft将添加的对象类之外)?
是。
在Java中,程序员没有办法保证对象的连续内存分配吗?
除非您使用了堆内存,否则不会。虽然通常情况下,这并不像大多数时候所想的那样是个问题,但是对象在内存中将是连续的。
它可能是偶然发生的,也可能是以很高的概率发生的,但程序员不能保证会这样吗?
对,是这样。通常,当你看到最糟糕的0.1%以上的延迟时,你会遇到更大的问题。
在C中,程序员可以在内存中连续地创建对象(结构)的原始数组,就像我前面所展示的那样,对吗?
是。您也可以在Java中这样做,但是您必须使用堆内存。支持这一点的库有很多,如this、纪事、SBE等。
发布于 2015-09-03 17:22:06
像C这样的低级语言可以让您处理内存布局,以及您是否有指向其他地方的指针,或者在这里有一个值。确保您正确地处理堆栈和堆分配,并且不要忘记free()
您malloc()
的每个指针。
像Java、Python和JavaScript这样的高级语言夺走了低级别内存布局。所有对象都在堆上,并且您有对它的引用。虽然引用类似于指针,但它是不透明的,并且不直接与给定的内存位置相关联。因此,所有数据结构都包含对对象的引用。
发布于 2015-09-03 17:29:41
在java中,数组是对象和对象,数组存储在堆上,因为堆可能不是连续的,所以数组也可能不是连续的。
4)在python中,如果使用枕骨,可以创建一个连续数组
https://stackoverflow.com/questions/32381773
复制相似问题