因此C语言有一个realloc()
过程,可用于就地扩展分配的[edit] 内存。
JVM / Java是否存在等效概念?是Array
还是nio.Buffer
?我不在乎这是JDK的一部分还是作为外部库,例如sun.unsafe
。
答案 0 :(得分:2)
首先,C函数realloc
不是可以增长 array 的工具,而是先前allocated via malloc
, calloc
, or realloc
的内存。相比之下,C数组可以驻留在堆栈或静态存储区域上,甚至可以嵌入更大的结构中。
然后,该函数具有使free
那样的原始指针无效并返回新指针的语义。因此,如果您有四处飞行的指针副本,则有责任用新指针替换所有出现的指针。
当然,Java不支持使引用无效。保证每个非null
对象引用的有效性,是Java内存管理的基本属性。
因此,如果要使用C的realloc
,则必须使用指针而不是数组。然后sun.misc.Unsafe
具有所有相关的操作
public long allocateMemory(long bytes)
public long reallocateMemory(long address, long bytes)
public void freeMemory(long address)
public float getXyz(long address)
¹public void putXyz(long address, xyz x)
¹¹其中“ xyz”代表原始类型
如果要调整数组大小,请使用
array = Arrays.copyOf(array, newSize);
这不会使旧引用无效,因此,如果您无法替换所有对旧数组的引用,则使用这些旧引用的代码将访问旧数组。
但是,如果array
是对特定数组的唯一引用,或者您的代码已被证明可以替换所有现有引用,则JVM在理论上可以启用就地调整大小操作,而不是复制内容,请参见也Does Java JIT cheat when running JDK code?
但是检查必要的先决条件可能比复制数组内容的开销更大。我能想象出适用性的唯一情况是,如果数组是同一线程分配的最后一个对象,那么可以证明引用还没有转义,并且分配空间内的数组后面没有对象。 / p>
对于具有这种优化的JVM,当您反复将其添加到ArrayList
时,您可能会自动获得好处,因为该类确保它是对其内部数组的唯一引用,并且使用{{ 3}}在内部用于调整大小。