我正在阅读有关数据局部性的信息,并希望使用它来改善我正在编写的游戏引擎。
假设我在不同的时间创建了五个对象,这些对象现在都位于内存中的不同位置,而不是彼此相邻。如果将它们全部添加到数组中,该数组将仅保留指向那些对象的指针,它们将保留在内存中的同一位置,或者将它们全部添加到数组中以重新排列它们并使它们连续。
我问这个问题是因为我认为使用数组是使它们连续的好方法,但是我不知道数组是否可以解决我的问题!
操作对对象的引用数组不会影响对象,也不会影响对象在内存中的位置。
一个阵列的对象是实在的引用(指针)的阵列的对象。甲指针是地址在存储器的另一个位置。
我们将数组称为保持对象,但这在技术上并不准确。因为Java不会将指针本身公开给我们作为程序员,所以我们通常不知道它们的存在。当我们访问数组中的元素时,实际上是在获取指针,但是Java会立即跟随该指针将对象定位在内存中的其他位置。
在指向对象的指针之后,这种自动查找使指针数组感觉像对象数组。Java程序员将她的数组视为持有对象的事实,而实际上这些对象是跳跃式跳跃的。
Java中的数组被实现为连续的内存块。对于对象数组,指向这些对象的指针存储在连续内存中。但是,当我们访问元素时,我们将跳转到内存中的另一个位置以访问所需的实际对象。
添加元素可能是“便宜的”,因为如果碰巧在内存中隔壁有可用的内存,则可以将其分配给数组以为更多的元素腾出空间。实际上,这是不可能的。很有可能是新数组必须在内存中的其他位置构建,所有指针都将被复制到新数组,然后丢弃原始数组。
这样的新阵列和复制是“昂贵的”。在可行的情况下,我们要避免执行此操作。如果您知道数组可能的最大大小,请在声明数组时指定该大小。立即声明整个连续内存块,数组中的内容为空,直到您以后将指针分配给元素为止。
插入数组中间也很昂贵。要么建立一个新的数组并复制元素,要么必须将插入点之后的所有元素向下移动到其相邻位置。
这些对数组的操作均不影响对象。对象在内存中漂浮。对象对数组一无所知。阵列上的操作不会影响对象,也不会影响它们在内存中的位置。唯一的关系是,如果数组中保存的引用是仍指向该对象的最后一个引用,则当清除或删除该数组元素时,该对象将成为垃圾收集的候选对象。
在Java中,八个原始类型(byte
,short
,int
,long
,float
,double
,boolean
,和char
)不是对象/类和不面向对象编程。优点之一是,与对象相比,它们速度快且占用的内存少。
基元数组将值保存在数组本身内。因此,这些值彼此相邻地存储在内存中。没有参考/指针。不会在内存中跳来跳去。
对于添加或插入,适用上面讨论的相同行为。除了代替改组指针之外,还改组实际的原始值。
在业务应用程序中,通常最好使用对象。
这意味着使用包装器类而不是基元。例如,Integer
代替int
。Java中的自动装箱功能通过在原始值及其对象包装器之间自动进行转换,使此操作变得更加容易。
首选对象意味着使用aCollection
而不是数组,通常是a List
,特别是a ArrayList
。或出于不可变的用途,List
从新List.of
方法返回的实现。
与业务应用程序相比,在极端情况下,如速度和内存使用至关重要,例如游戏引擎,则可以充分利用数组和基元。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句