Java 1.8 Unsafe
2021-06-29 08:05
标签:内存屏障 ldo 运行 完成 wapi ror realloc should val Unsafe 类在 sun.misc 包下,不属于Java标准。但是很多 Java 的基础类库,以及优秀的三方库都会用这个提升性能。 Unsafe 使用了单例模式,想使用 Unsafe 类就需要获取实例。由于安全限制,不能用一般的方法获取这个实例,通常都是使用反射获取 Unsafe 类几类功能: long allocateMemory(long bytes) 向操作系统申请一块本地内存,大小为 bytes 字节,返回内存块的地址。本地内存是指不由 JVM 管理的内存,不会被 GC 管理。 底层使用 malloc 实现 long reallocateMemory(long address, long bytes) resize 一块本地内存,address 是原内存地址, bytes 是新大小。 如果 address 是 0,则内部用 allocateMemory 分配新内存;如果 bytes 是 0,则用 freeMemory 释放原内存。 底层使用 realloc 实现。 void freeMemory(long address) 释放由 allocateMemory 申请的内存 底层用 free 实现 int pageSize() 返回一页内存的大小 int addressSize() 返回一个指针的大小 内存操作需要提供地址。UnSafe 需要地址的场合会需要两个参数 Object o, long offset 如果 o 是 null, offset 将被视为具体的内存地址; 如果 o 非 null,offset 被为字段在对象或数组中的偏移。 o 和 offset 一起得到一个有效地址 void setMemory(Object o, long offset, long bytes, byte value) 将一块内存设置为固定值。 void setMemory(long address, long bytes, byte value) 等价于 setMemory(null, address, bytes, value); void copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes) 复制内存 void copyMemory(long srcAddress, long destAddress, long bytes) 等价于 copyMemory(null, srcAddress, null, destAddress, bytes) put / get 系列 T getT(Object o, long offset) void putT(Object o, long offset, T x) T 可以是 int、boolean、byte、short、char、long、float、double 另外还有不需要 Object o 参数的版本,等价于 getT(null, address) Object getObject(Object o, long offset) void putObject(Object o, long offset, Object x) T getTVolatile(Object o, long offset) void putTVolatile(Object o, long offset, T x) 带 volatile 语义的 put / get long getAddress(Object o, long offset) 从指定地址获取一个内存指针 void putAddress(Object o, long offset, long x) 将指针存到指定地址 void putOrderedObject(Object o, long offset, Object x) void putOrderedInt(Object o, long offset, int x) void putOrderedLong(Object o, long offset, long x) 保证写后立即可见 long staticFieldOffset(Field f) 返回一个静态字段的内存位置 long objectFieldOffset(Field f) 返回一个指定字段的存储位置 Object staticFieldBase(Field f) 返回一个静态字段的存储位置,是一个引用 Object allocateInstance(Class> cls) 创建一个类实例,但不执行构造方法 int arrayBaseOffset(Class> arrayClass) 返回 arrayClass 类型数组的第 0 个元素到数组对象内存开始的偏移 int arrayIndexScale(Class> arrayClass) 返回一个数组元素需要的长度大小 void throwException(Throwable ee) 该方法抛出受检异常,但代码不必捕捉或重新抛出它,正如运行时异常一样 Class> defineClass(String name, byte[] b, int off, int len, ClassLoader loader, ProtectionDomain protectionDomain) 从字节码创建一个类 Class> defineAnonymousClass(Class> hostClass, byte[] data, Object[] cpPatches) 从字节码创建匿名类 void ensureClassInitialized(Class> c) 加载类 boolean shouldBeInitialized(Class> c) 检查类是否已加载 void monitorEnter(Object obj) 锁定对象 void monitorExit(Object obj) 释放锁 monitorEnter 和 monitorExit 的组合相当于 synchronized 关键字 boolean tryMonitorEnter(Object obj) 尝试锁定对象 以上 3 个都是 @Deprecated 的方法 boolean compareAndSwapObject(Object o, long offset, Object expected, Object x) boolean compareAndSwapInt(Object o, long offset, int expected, int x) boolean compareAndSwapLong(Object o, long offset, long expected, long x) 如果变量的值是 expected,则更新成 x,原子更新 int getAndAddInt(Object o, long offset, int delta) long getAndAddLong(Object o, long offset, long delta) 原子加 getAndSetInt(Object o, long offset, int newValue) getAndSetLong(Object o, long offset, long newValue) getAndSetObject(Object o, long offset, Object newValue) 原子地设置新值和返回旧值 void park(boolean isAbsolute, long time) 暂停当前线程 void unpark(Object thread) 通知线程恢复 JDK concurrent 包的锁大部分用这个实现 void loadFence() 在该方法之前的所有读操作,一定在load屏障之前执行完成 void storeFence() 在该方法之前的所有写操作,一定在store屏障之前执行完成 void fullFence() 在该方法之前的所有读写操作,一定在full屏障之前执行完成,这个内存屏障相当于上面两个的合体功能 Java 1.8 Unsafe 标签:内存屏障 ldo 运行 完成 wapi ror realloc should val 原文地址:https://www.cnblogs.com/randomsort/p/9641983.htmlpublic class UnsafeDemo {
static sun.misc.Unsafe U;
static {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
U = (Unsafe) f.get(null);
} catch (Exception e) {
throw new Error(e);
}
}
}
内存管理
内存操作
计算类字段内存位置
非常规的对象实例化
数组操作
异常
动态类
多线程同步
原子操作
挂起与恢复
内存屏障