可以重新分配JVM数组吗?

时间:2019-05-25 15:10:50

标签: java jvm realloc

因此C语言有一个realloc()过程,可用于就地扩展分配的[edit] 内存

JVM / Java是否存在等效概念?是Array还是nio.Buffer?我不在乎这是JDK的一部分还是作为外部库,例如sun.unsafe

1 个答案:

答案 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}}在内部用于调整大小。