1 回答
TA贡献1775条经验 获得超8个赞
首先,C 函数realloc
不是可以增长数组的工具,而是以前通过、或分配malloc
calloc
realloc
的内存。相反,C 数组可能位于堆栈或静态内存区域,甚至可能嵌入更大的结构中。
然后,该函数具有使原始指针无效free
并返回新指针的语义。所以如果你有指针的副本到处乱飞,你有责任用新指针替换所有出现的地方。
当然,Java 不支持无效引用。保证每个非null
对象引用的有效性,是 Java 内存管理的基本属性。
所以如果你想要 C's 的等价物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?
但是检查必要的先决条件可能比复制数组内容更昂贵。我可以想象适用性的唯一场景是,如果数组是同一线程分配的最后一个对象,那么可以证明引用还没有逃逸,并且在分配空间中数组后面没有对象。
对于具有这种优化的 JVM,当重复添加到 时,您可能会自动获得好处ArrayList
,因为该类确保它是对其内部数组的引用的唯一持有者,并且它在Arrays.copyOf
内部用于调整大小。
添加回答
举报