Mmc秒杀圈百科 

Unsafe

由 mcst12345管理员 最后编辑于 2026-10-04 04:16 · 当前版本 v4
标签:技术正经内容
你尚未登录。登录后可编辑本页与创建新条目 —— 登录 或 注册账号。

Unsafe(sun.misc.Unsafe,*Java9+ 位于 jdk.unsupported 模块)提供直接内存读写、字段偏移、CAS、不经构造器创建对象等底层操作,绕过 Java 的访问检查和类型安全。自Java9開始sun.misc.Unsafe為jdk.internal.misc.Unsafe的封裝。

获取

构造器私有,通常用 Reflection 读取静态字段 theUnsafe:
Field f = Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); Unsafe u = (Unsafe) f.get(null);

常用能力

  • objectFieldOffset / staticFieldBase / staticFieldOffset 配合 getObject、putObject、getInt、putInt 等:直接读写任意字段,包括 final 字段。
  • allocateInstance:不调用构造器创建对象。
  • compareAndSwap* / getAndSet*:原子操作。
  • allocateMemory / freeMemory / getAddress / putAddress:堆外内存。
  • 读写对象头:klassptr 就是用 getInt / putInt 改写对象头里的类型指针,从而改变对象在 JVM 眼中的类型。
  • 读取 MethodHandles.Lookup.IMPL_LOOKUP 等 JDK 内部静态字段,见 MethodHandle。
  • 修改 Klass 内部标志:例如清除隐藏类的 hidden 标志,使它被当作普通类,从而能被 retransformClasses / redefineClasses 处理;依赖 JDK 内部布局,不同版本需要适配。

局限

  • 偏移量或地址写错可能会直接导致非法內存訪問。
  • 对 record 和隐藏类的字段,objectFieldOffset 会抛异常。
  • defineClass ,defineAnonymousClass 已於 JDK 11/17 移除並遷移至 MethodHandles.Lookup。
  • JDK 23 起,sun.misc.Unsafe 的内存访问方法被标记为弃用待删除(JEP 471)。

Unsafe class is mainly used for raw memory access. Before Java 9 there's only sun.misc.Unsafe, after that sun.misc.Unsafe has became a wrapper for jdk.internal.misc.Unsafe

Capability

Unsafe can be used to read/write most primitive types from/to a specific memoy address through methods like getInt(long), putInt(long,int). There are also volatile variants like getIntVolatile and putIntVolatile. There are also oop variants such as getInt(Object,long) to access memory based on the address of a Java object, which can be used to access object fields. There's objectFieldOffset and staticFieldOffset methods to obtain offset of object/static fields. For static field there's a staticFieldBase method to obtain the "base" object when accessing static fields, however it's just the field's declaring class so that you can just use field.getDeclaringClass() instead. There's also getReference/getObject/putReference/putObject (the name depends on your Java version) to fetch/write Java objects.
Unsafe can also be used to manage off-heap memory using allocateMemory,freeMemory,reallocateMemory methods.
Unsafe.allocateInstance(Class) can be used to allocate a Java object without invoking <init> which means that the object is uninitialized.
Unsafe also supports CAS operations. There are many *compareAndSet* methods.
arrayBaseOffset and arrayIndexScale are used to access Java array using Unsafe. arrayBaseOffset returns the offset of the first element of a Java array based on the array object itself, arrayIndexScale returns the size of each element for an array type.
//TODO

Notes

  • Unsafe is marked for deprecated for a long time, though it has never been removed. However it has changed significantly that most of its apis aren't persistent across Java versions.
  • An illegal memory access will crash JVM.
你对本条的回应 · 登录后可表态

讨论(0)

讨论不进入条目正文的版本历史,适合提出修改建议、指出问题或补充来源。
还没有人讨论这个条目。你可以提出修改建议、指出问题或补充来源。

发表话题

请先 登录 后再参与讨论。