为了账号安全,请及时绑定邮箱和手机立即绑定

JVM 数组可以重新分配()吗?

JVM 数组可以重新分配()吗?

慕村225694 2022-12-15 16:41:50
所以 C 语言有一个realloc()程序可以用来就地增加分配的 [edit]内存。JVM/Java 是否存在等效概念?为Arrays还是nio.Buffers?我不介意这是 JDK 的一部分还是作为外部库,例如sun.unsafe.
查看完整描述

1 回答

?
www说

TA贡献1775条经验 获得超8个赞

首先,C 函数realloc不是可以增长数组的工具,而是以前通过分配malloccallocrealloc的内存。相反,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内部用于调整大小。


查看完整回答
反对 回复 2022-12-15
  • 1 回答
  • 0 关注
  • 53 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信