欢迎来到冰点文库! | 帮助中心 分享价值,成长自我!
冰点文库
全部分类
  • 临时分类>
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • ImageVerifierCode 换一换
    首页 冰点文库 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    Java Unsafe 类.docx

    • 资源ID:15280187       资源大小:21.10KB        全文页数:20页
    • 资源格式: DOCX        下载积分:5金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要5金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    Java Unsafe 类.docx

    1、Java Unsafe 类Java Unsafe 类Unsafe类是啥?Java最初被设计为一种安全的受控环境。尽管如此,Java HotSpot还是包含了一个“后门”,提供了一些可以直接操控内存和线程的低层次操作。这个后门类sun.misc.Unsafe被JDK广泛用于自己的包中,如java.nio和java.util.concurrent。但是丝毫不建议在生产环境中使用这个后门。因为这个API十分不安全、不轻便、而且不稳定。这个不安全的类提供了一个观察HotSpot JVM内部结构并且可以对其进行修改。有时它可以被用来在不适用C+调试的情况下学习虚拟机内部结构,有时也可以被拿来做性能监控和

    2、开发工具。为什么叫Unsafe?Java官方不推荐使用Unsafe类,因为官方认为,这个类别人很难正确使用,非正确使用会给JVM带来致命错误。而且未来Java可能封闭丢弃这个类。如何使用Unsafe?1. 获取Unsafe实例:通读Unsafe源码,Unsafe提供了一个私有的静态实例,并且通过检查classloader是否为null来避免java程序直接使用unsafe:/Unsafe源码private static final Unsafe theUnsafe;CallerSensitivepublic static Unsafe getUnsafe() Class var0 = Refl

    3、ection.getCallerClass(); if(var0.getClassLoader() != null) throw new SecurityException(Unsafe); else return theUnsafe; 我们可以通过如下代码反射获取Unsafe静态类:/* * 获取Unsafe */Field f = null;Unsafe unsafe = null;try f = Unsafe.class.getDeclaredField(theUnsafe); f.setAccessible(true); unsafe = (Unsafe) f.get(null); c

    4、atch (NoSuchFieldException e) e.printStackTrace(); catch (IllegalAccessException e) e.printStackTrace();2. 通过Unsafe分配使用堆外内存:C+中有malloc,realloc和free方法来操作内存。在Unsafe类中对应为:/分配var1字节大小的内存,返回起始地址偏移量public native long allocateMemory(long var1);/重新给var1起始地址的内存分配长度为var3字节大小的内存,返回新的内存起始地址偏移量public native long

    5、 reallocateMemory(long var1, long var3);/释放起始地址为var1的内存public native void freeMemory(long var1);分配内存方法还有重分配内存方法都是分配的堆外内存,返回的是一个long类型的地址偏移量。这个偏移量在你的Java程序中每块内存都是唯一的。 举例:/* * 在堆外分配一个byte */long allocatedAddress = unsafe.allocateMemory(1L);unsafe.putByte(allocatedAddress, (byte) 100);byte shortValue =

    6、 unsafe.getByte(allocatedAddress);System.out.println(new StringBuilder().append(Address:).append(allocatedAddress).append( Value:).append(shortValue);/* * 重新分配一个long */allocatedAddress = unsafe.reallocateMemory(allocatedAddress, 8L);unsafe.putLong(allocatedAddress, 1024L);long longValue = unsafe.get

    7、Long(allocatedAddress);System.out.println(new StringBuilder().append(Address:).append(allocatedAddress).append( Value:).append(longValue);/* * Free掉,这个数据可能脏掉 */unsafe.freeMemory(allocatedAddress);longValue = unsafe.getLong(allocatedAddress);System.out.println(new StringBuilder().append(Address:).app

    8、end(allocatedAddress).append( Value:).append(longValue);输出:Address:46490464 Value:100Address:46490480 Value:1024Address:46490480 Value:223. 操作类对象我们可以通过Unsafe类来操作修改某一field。原理是首先获取对象的基址(对象在内存的偏移量起始地址)。之后获取某个filed在这个对象对应的类中的偏移地址,两者相加修改。 /* * 获取类的某个对象的某个field偏移地址 */try f = SampleClass.class.getDeclaredF

    9、ield(i); catch (NoSuchFieldException e) e.printStackTrace();long iFiledAddressShift = unsafe.objectFieldOffset(f);SampleClass sampleClass = new SampleClass();/获取对象的偏移地址,需要将目标对象设为辅助数组的第一个元素(也是唯一的元素)。由于这是一个复杂类型元素(不是基本数据类型),它的地址存储在数组的第一个元素。然后,获取辅助数组的基本偏移量。数组的基本偏移量是指数组对象的起始地址与数组第一个元素之间的偏移量。Object helper

    10、Array = new Object1;helperArray0 = sampleClass;long baseOffset = unsafe.arrayBaseOffset(Object.class);long addressOfSampleClass = unsafe.getLong(helperArray, baseOffset);int i = unsafe.getInt(addressOfSampleClass + iFiledAddressShift);System.out.println(new StringBuilder().append( Field I Address:).

    11、append(addressOfSampleClass).append(+).append(iFiledAddressShift).append( Value:).append(i);输出:Field I Address:3610777760+24 Value:54. 线程挂起和恢复将一个线程进行挂起是通过park方法实现的,调用 park后,线程将一直阻塞直到超时或者中断等条件出现。unpark可以终止一个挂起的线程,使其恢复正常。整个并发框架中对线程的挂起操作被封装在 LockSupport类中,LockSupport类中有各种版本pack方法,但最终都调用了Unsafe.park()方法

    12、。public class LockSupport public static void unpark(Thread thread) if (thread != null) unsafe.unpark(thread); public static void park(Object blocker) Thread t = Thread.currentThread(); setBlocker(t, blocker); unsafe.park(false, 0L); setBlocker(t, null); public static void parkNanos(Object blocker, l

    13、ong nanos) if (nanos 0) Thread t = Thread.currentThread(); setBlocker(t, blocker); unsafe.park(false, nanos); setBlocker(t, null); public static void parkUntil(Object blocker, long deadline) Thread t = Thread.currentThread(); setBlocker(t, blocker); unsafe.park(true, deadline); setBlocker(t, null);

    14、public static void park() unsafe.park(false, 0L); public static void parkNanos(long nanos) if (nanos 0) unsafe.park(false, nanos); public static void parkUntil(long deadline) unsafe.park(true, deadline); 5. CAS操作/* * 比较obj的offset处内存位置中的值和期望的值,如果相同则更新。此更新是不可中断的。 * * param obj 需要更新的对象 * param offset o

    15、bj中整型field的偏移量 * param expect 希望field中存在的值 * param update 如果期望值expect与field的当前值相同,设置filed的值为这个新值 * return 如果field的值被更改返回true */ public native boolean compareAndSwapInt(Object obj, long offset, int expect, int update); 6. Clone如何实现浅克隆?在clone()方法中调用super.clone(),对吗?这里存在的问题是首先你必须继续Cloneable接口,并且在所有你需要做

    16、浅克隆的对象中实现clone()方法,对于一个懒懒的程序员来说,这个工作量太大了。 我不推荐上面的做法而是直接使用Unsafe,我们可以仅使用几行代码就实现浅克隆,并且它可以像某些工具类一样用于任意类的克隆。首先,我们需要一个计算Object大小的工具类:class ObjectInfo /* * Field name */ public final String name; /* * Field type name */ public final String type; /* * Field data formatted as string */ public final String c

    17、ontents; /* * Field offset from the start of parent object */ public final int offset; /* * Memory occupied by this field */ public final int length; /* * Offset of the first cell in the array */ public final int arrayBase; /* * Size of a cell in the array */ public final int arrayElementSize; /* *

    18、Memory occupied by underlying array (shallow), if this is array type */ public final int arraySize; /* * This object fields */ public final List children; public ObjectInfo(String name, String type, String contents, int offset, int length, int arraySize, int arrayBase, int arrayElementSize) this.nam

    19、e = name; this.type = type; this.contents = contents; this.offset = offset; this.length = length; this.arraySize = arraySize; this.arrayBase = arrayBase; this.arrayElementSize = arrayElementSize; children = new ArrayList(1); public void addChild(final ObjectInfo info) if (info != null) children.add(

    20、info); /* * Get the full amount of memory occupied by a given object. This value may be slightly less than * an actual value because we dont worry about memory alignment - possible padding after the last object field. * * The result is equal to the last field offset + last field length + all array s

    21、izes + all child objects deep sizes * * return Deep object size */ public long getDeepSize() /return length + arraySize + getUnderlyingSize( arraySize != 0 ); return addPaddingSize(arraySize + getUnderlyingSize(arraySize != 0); long size = 0; private long getUnderlyingSize(final boolean isArray) /lo

    22、ng size = 0; for (final ObjectInfo child : children) size += child.arraySize + child.getUnderlyingSize(child.arraySize != 0); if (!isArray & !ldren.isEmpty() int tempSize = children.get(children.size() - 1).offset + children.get(children.size() - 1).length; size += addPaddingSize(tempSize); return s

    23、ize; private static final class OffsetComparator implements Comparator Override public int compare(final ObjectInfo o1, final ObjectInfo o2) return o1.offset - o2.offset; /safe because offsets are small non-negative numbers /sort all children by their offset public void sort() Collections.sort(child

    24、ren, new OffsetComparator(); Override public String toString() final StringBuilder sb = new StringBuilder(); toStringHelper(sb, 0); return sb.toString(); private void toStringHelper(final StringBuilder sb, final int depth) depth(sb, depth).append(name=).append(name).append(, type=).append(type) .app

    25、end(, contents=).append(contents).append(, offset=).append(offset) .append(, length=).append(length); if (arraySize 0) sb.append(, arrayBase=).append(arrayBase); sb.append(, arrayElemSize=).append(arrayElementSize); sb.append(, arraySize=).append(arraySize); for (final ObjectInfo child : children) s

    26、b.append(n); child.toStringHelper(sb, depth + 1); private StringBuilder depth(final StringBuilder sb, final int depth) for (int i = 0; i depth; +i) sb.append(t); return sb; private long addPaddingSize(long size) if (size % 8 != 0) return (size / 8 + 1) * 8; return size; class ClassIntrospector priva

    27、te static final Unsafe unsafe; /* * Size of any Object reference */ private static final int objectRefSize; static try Field field = Unsafe.class.getDeclaredField(theUnsafe); field.setAccessible(true); unsafe = (Unsafe) field.get(null); objectRefSize = unsafe.arrayIndexScale(Object.class); catch (Ex

    28、ception e) throw new RuntimeException(e); /* * Sizes of all primitive values */ private static final Map primitiveSizes; static primitiveSizes = new HashMap(10); primitiveSizes.put(byte.class, 1); primitiveSizes.put(char.class, 2); primitiveSizes.put(int.class, 4); primitiveSizes.put(long.class, 8);

    29、 primitiveSizes.put(float.class, 4); primitiveSizes.put(double.class, 8); primitiveSizes.put(boolean.class, 1); /* * Get object information for any Java object. Do not pass primitives to * this method because they will boxed and the information you will get will * be related to a boxed version of your value. * * param obj Object to introspect * return Object info * throws IllegalAccessException */ public ObjectInfo introspect(final Object obj) throws IllegalAccessException try return introspect(obj, null); finally / clean visited cache before returning in order to make / this object r


    注意事项

    本文(Java Unsafe 类.docx)为本站会员主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2023 冰点文库 网站版权所有

    经营许可证编号:鄂ICP备19020893号-2


    收起
    展开