【FCon上海】与行业领袖共话AI大模型、数字化风控等前沿技术。 了解详情
写点什么

JEP 456:准备删除 Unsafe 中的内存访问方法

  • 2024-07-10
    北京
  • 本文字数:2964 字

    阅读完需:约 10 分钟

JEP 456:准备删除 Unsafe 中的内存访问方法

AI 大模型超全落地场景&金融应用实践,8 月 16 - 19 日 FCon x AICon 大会联诀来袭、干货翻倍!

JEP 471(弃用 sun.misc.Unsafe 中的内存访问方法以备删除)已经在 JDK 23 中发布。该 JEP 建议弃用 Unsafe 类中的内存访问方法,以便在将来的版本中删除。这些不再支持的方法已经被标准 API 所取代:JEP 193(变量句柄,已在 JDK 9 中交付)和 JEP 454(外部函数和内存 API,已在 JDK 22 中交付)。


弃用这些方法的主要目的是为最终删除sun.misc.Unsafe中的内存访问方法做准备。编译时和运行时警告会突出显示这些方法的使用情况,开发人员可以借此识别并迁移到受支持的替代方法。这一转变的目标是确保应用程序能够顺利过渡到现代 JDK 版本,从而增强安全性和性能。


现在,有两个标准 API 为sun.misc.Unsafe提供了安全高效的替代方案。VarHandle API(即在 JDK 9 中交付的 JEP 193)提供了安全操作堆内存的方法,可以确保操作有效执行并且不会出现未定义的行为。外部函数和内存 API(即在 JDK 22 中交付的 JEP 454)提供了安全的堆外内存访问方法,通常与 VarHandle 搭配使用来管理 JVM 堆内和堆外内存。这些 API 承诺:不会出现未定义的行为、长期稳定以及更好地与 Java 工具和文档集成。


已弃用的sun.misc.Unsafe方法分为三类:堆内、堆外和双模(可以访问堆内和堆外内存的方法)。堆内方法包括:


long objectFieldOffset(Field f)long staticFieldOffset(Field f)Object staticFieldBase(Field f)int arrayBaseOffset(Class<?> arrayClass)int arrayIndexScale(Class<?> arrayClass)
复制代码


这些方法可以用VarHandleMemorySegment::ofArray及其重载方法代替。例如,考虑下面的例子:


class Foo {
private static final Unsafe UNSAFE = ...; // 一个 sun.misc.Unsafe 对象
private static final long X_OFFSET;
static { try { X_OFFSET = UNSAFE.objectFieldOffset(Foo.class.getDeclaredField("x")); } catch (Exception ex) { throw new AssertionError(ex); } }
private int x;
public boolean tryToDoubleAtomically() { int oldValue = x; return UNSAFE.compareAndSwapInt(this, X_OFFSET, oldValue, oldValue * 2); }}
复制代码


上述代码可以用 VarHandle 实现如下:


class Foo {
private static final VarHandle X_VH;
static { try { X_VH = MethodHandles.lookup().findVarHandle(Foo.class, "x", int.class); } catch (Exception ex) { throw new AssertionError(ex); } }
private int x;
public boolean tryAtomicallyDoubleX() { int oldValue = x; return X_VH.compareAndSet(this, oldValue, oldValue * 2); }}
复制代码


堆外方法主要有以下这些:


long allocateMemory(long bytes)long reallocateMemory(long address, long bytes)void freeMemory(long address)void invokeCleaner(java.nio.ByteBuffer directBuffer)void setMemory(long address, long bytes, byte value)void copyMemory(long srcAddress, long destAddress, long bytes)[type] get[Type](long address)void put[Type](long address, [type] x)
复制代码


这些方法可以用MemorySegment 操作替换。考虑下面的例子:


class OffHeapIntBuffer {
private static final Unsafe UNSAFE = ...;
private static final int ARRAY_BASE = UNSAFE.arrayBaseOffset(int[].class); private static final int ARRAY_SCALE = UNSAFE.arrayIndexScale(int[].class);
private final long size; private long bufferPtr;
public OffHeapIntBuffer(long size) { this.size = size; this.bufferPtr = UNSAFE.allocateMemory(size * ARRAY_SCALE); }
public void deallocate() { if (bufferPtr == 0) return; UNSAFE.freeMemory(bufferPtr); bufferPtr = 0; }
private boolean checkBounds(long index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException(index); return true; }
public void setVolatile(long index, int value) { checkBounds(index); UNSAFE.putIntVolatile(null, bufferPtr + ARRAY_SCALE * index, value); }
public void initialize(long start, long n) { checkBounds(start); checkBounds(start + n-1); UNSAFE.setMemory(bufferPtr + start * ARRAY_SCALE, n * ARRAY_SCALE, 0); }
public int[] copyToNewArray(long start, int n) { checkBounds(start); checkBounds(start + n-1); int[] a = new int[n]; UNSAFE.copyMemory(null, bufferPtr + start * ARRAY_SCALE, a, ARRAY_BASE, n * ARRAY_SCALE); return a; }
}
复制代码


上述代码使用标准 API ArenaMemorySegment 替换后如下:


class OffHeapIntBuffer {
private static final VarHandle ELEM_VH = ValueLayout.JAVA_INT.arrayElementVarHandle();
private final Arena arena; private final MemorySegment buffer;
public OffHeapIntBuffer(long size) { this.arena = Arena.ofShared(); this.buffer = arena.allocate(ValueLayout.JAVA_INT, size); }
public void deallocate() { arena.close(); }
public void setVolatile(long index, int value) { ELEM_VH.setVolatile(buffer, 0L, index, value); }
public void initialize(long start, long n) { buffer.asSlice(ValueLayout.JAVA_INT.byteSize() * start, ValueLayout.JAVA_INT.byteSize() * n) .fill((byte) 0); }
public int[] copyToNewArray(long start, int n) { return buffer.asSlice(ValueLayout.JAVA_INT.byteSize() * start, ValueLayout.JAVA_INT.byteSize() * n) .toArray(ValueLayout.JAVA_INT); }
}
复制代码


迁移将分几个阶段进行,每个阶段对应一个单独的 JDK 版本。在第一阶段(从 JDK 23 开始),所有内存访问方法都将被弃用,并且将发出编译时警告。第二阶段(计划从 JDK 25 或更早的版本开始)将在发现使用已弃用方法的情况时发出运行时警告。第三阶段(计划从 JDK 26 或更高的版本开始)将进一步升级响应,在发现对这些方法的调用时默认抛出异常。最后,第四和第五阶段将删除已弃用的方法。这两个阶段可能发生在同一版本中。开发人员可以使用新增的命令行选项--sun-misc-unsafe-memory-access={allow|warn|debug|deny}来管理弃用警告并评估对其应用程序的影响。


弃用sun.misc.Unsafe内存访问方法是增强 Java 平台完整性和安全性的一个重要步骤。借助 VarHandle 及外部函数和内存 API,开发人员可以保证其应用程序的健壮性,并兼容未来的 JDK 版本。这种分阶段的方法为迁移提供了充足的时间,既有助于 Java 开发最佳实践的推广,又能够尽可能地减少由此带来的影响。


原文链接:

https://www.infoq.com/news/2024/06/jep-456-removing-unsafe-methods/

2024-07-10 08:003683

评论

发布
暂无评论

OmniFocus Pro 4 for mac(最佳GTD时间效率工具)

Mac相关知识分享

软件下载

GM EPUB Reader Pro for Mac(专业ePub阅读神器)

Mac相关知识分享

阅读软件

系列三:被大数据"套牢"的产品经理:危机重重下如何突围?

松子(李博源)

数据中台 AI 数据产品经理 数据产品 #大模型

FxFactory 8 Pro for Mac(视觉特效处理包)

Mac相关知识分享

视觉特效软件包

Cardhop for Mac(通讯录管理工具)v2.2.18汉化版

影影绰绰一往直前

HarmonyOS NEXT 赋能小红书,引领社交媒体平台全新沉浸式体验

最新动态

区块链与NFT

dappweb

区块链 ao

AI在区块链供应链管理中有何应用

dappweb

区块链 ao

SnapMotion for Mac v5.2.4 视频截图工具 中文激活版

影影绰绰一往直前

Airtool for Mac v2.5.4 系统菜单栏网络工具 激活版

影影绰绰一往直前

Dynamic Wallpaper for Mac(Mac动态壁纸桌面)v18.6中文版

影影绰绰一往直前

基于LangChain手工测试用例生成工具

霍格沃兹测试开发学社

区块链与去中心化应用开发

dappweb

区块链 ao

博睿数据受邀出席GOPS全球运维大会北京站,分享《一体化可观测数据模型和AIOps的融合实践》

博睿数据

3家券商综合评级上升,5月券商App终端业务体验评测报告发布

博睿数据

MES系统对车间生产的实时监控和数据分析功能

万界星空科技

生产管理系统 mes 万界星空科技 生产管理

如何开发属于你自己的游戏直播软件平台:四步走战略

软件开发-梦幻运营部

TikTok多账号怎么稳定的运营?Ownips静态住宅IP代理测评

陈橘又青

区块链与代币开发

dappweb

区块链 ao

HarmonyOS NEXT助力微博创新:多媒体体验与性能的双重突破

最新动态

多租户与低代码开发的应用:解锁企业数字化转型的无限可能

快乐非自愿限量之名

低代码 数字化 多租户

HarmonyOS NEXT赋能南方航空,打造民航出行的极简高效体验

最新动态

AI如何识别并纠正合同中的法律风险

dappweb

ao

Xliff Editor for Mac(Mac平台XLIFF文件编辑工具)

Mac相关知识分享

软件 软件下载

Dash for Mac(好用的API文档工具)v7.2.3版

Mac相关知识分享

API文档

iBarcoder for Mac v3.15.5 条形码生成工具 激活版

影影绰绰一往直前

Valentina Studio Pro for Mac(专业的数据库管理软件)v14.1.2激活版

影影绰绰一往直前

Rumpus Pro 10 for Mac v10.0.8 ftp文件传输服务器 激活版

影影绰绰一往直前

万界星空科技MES系统功能介绍

万界星空科技

ERP mes 万界星空科技

区块链与链游开发

dappweb

区块链 ao

AI会超越区块链吗

dappweb

区块链 ao

JEP 456:准备删除 Unsafe 中的内存访问方法_编程语言_A N M Bazlur Rahman_InfoQ精选文章