sun.misc.unsafe类的使用(转载)

Java魔法类 Unsafe应用解析 Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。 阅读详情

Java是一个安全的开发工具,它阻止开发人员犯很多低级的错误,而大部份的错误都是基于内存管理方面的。如果你想搞破坏,可以使用Unsafe这个类。这个类是属于sun.* API中的类,并且它不是J2SE中真正的一部份,因此你可能找不到任何的官方文档,更可悲的是,它也没有比较好的代码文档。


    实例化sun.misc.Unsafe

    如果你尝试创建Unsafe类的实例,基于以下两种原因是不被允许的。

    1)、Unsafe类的构造函数是私有的;

    2)、虽然它有静态的getUnsafe()方法,但是如果你尝试调用Unsafe.getUnsafe(),会得到一个SecutiryException。这个类只有被JDK信任的类实例化。

    但是这总会是有变通的解决办法的,一个简单的方式就是使用反射进行实例化:

Field f = Unsafe.class.getDeclaredField("theUnsafe"); //Internal reference
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);

注:IDE如Eclipse对会这样的使用报错,不过不用担心,直接运行代码就行,可以正常运行的。

    (译者注:还有一种解决方案,就是将Eclipse中这种限制获取由错误,修改为警告,具体操作为将Windows->Preference...->Java->Compiler->Errors/Warnings中的"Deprecated and restricted API",级别由Error修改为Warning就可以了)

    现在进入主题,使用这个对象我们可以做如下“有趣的”事情。


    使用sun.misc.Unsafe

    1)、突破限制创建实例

    通过allocateInstance()方法,你可以创建一个类的实例,但是却不需要调用它的构造函数、初使化代码、各种JVM安全检查以及其它的一些底层的东西。即使构造函数是私有,我们也可以通过这个方法创建它的实例。

    (这个对单例模式情有独钟的程序员来说将会是一个噩梦,它们没有办法阻止这种方式调用大笑)

    看下面一个实例(注:为了配合这个主题,译者将原实例中的public构造函数修改为了私有的):

public class UnsafeDemo {
	public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
		Field f = Unsafe.class.getDeclaredField("theUnsafe"); // Internal reference
		f.setAccessible(true);
		Unsafe unsafe = (Unsafe) f.get(null);

		// This creates an instance of player class without any initialization
		Player p = (Player) unsafe.allocateInstance(Player.class);
		System.out.println(p.getAge()); // Print 0

		p.setAge(45); // Let's now set age 45 to un-initialized object
		System.out.println(p.getAge()); // Print 45
	}
}

class Player {
	private int age = 12;

	private Player() {
		this.age = 50;
	}

	public int getAge() {
		return this.age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}


2)、使用直接获取内存的方式实现浅克隆

    如何实现浅克隆?在clone(){...}方法中调用super.clone(),对吗?这里存在的问题是首先你必须继续Cloneable接口,并且在所有你需要做浅克隆的对象中实现clone()方法,对于一个懒懒的程序员来说,这个工作量太大了。

    我不推荐上面的做法而是直接使用Unsafe,我们可以仅使用几行代码就实现浅克隆,并且它可以像某些工具类一样用于任意类的克隆。

    这个戏法就是把一个对象的字节码拷贝到内存的另外一个地方,然后再将这个对象转换为被克隆的对象类型。

    

    3)、来自黑客的密码安全

    这个好似很有趣吧?实事就是这样的。开发人员创建密码或者是保证密码到字符串中,然后在应用程序的代码中使用这些密码,使用过后,聪明的程序员会把字符串的引用设为NULL,因此它就不会被引用着并且很容易被垃圾收集器给回收掉。

    但是从你将引用设为NULL到被垃圾收集器收集的这个时间段之内(原文:But from the time, you made the reference null to the time garbage collector kicks in),它是处于字符串池中的,并且在你系统中进行一个复杂的攻击(原文:And a sophisticated attack on your system),也是可以读取到你的内存区域并且获得密码,虽然机会很小,但是总是存在的。

    这就是为什么建议使用char[]数组存放密码,当使用完过后,你可以迭代处理当前数组,修改/清空这些字符。

    另外一个方式就是使用魔术类Unsafe。你可以创建另外一个和当前密码字符串具有相同长度的临时字符串,将临时密码中的每个字符都设值为"?"或者"*"(任何字符都可以),当你完成密码的逻辑后,你只需要简单的将临时密码中的字节数组拷贝到原始的密码串中,这就是使用临时密码覆盖真实的密码。

    示例代码可能会是这样:

String password = new String("l00k@myHor$e");
String fake = new String(password.replaceAll(".", "?"));
System.out.println(password); // l00k@myHor$e
System.out.println(fake); // ????????????
 
getUnsafe().copyMemory(fake, 0L, null, toAddress(password), sizeOf(password));
 
System.out.println(password); // ????????????
System.out.println(fake); // ????????????

 运行时动态创建类

    我们可以在运行时运态的创建类,例如通过编译后的.class文件,操作方式就是将.class文件读取到字节数据组中,并将其传到defineClass方法中。

//Sample code to craeet classes
byte[] classContents = getClassContent();
Class c = getUnsafe().defineClass(null, classContents, 0, classContents.length);
c.getMethod("a").invoke(c.newInstance(), null);
 
//Method to read .class file
private static byte[] getClassContent() throws Exception {
    File f = new File("/home/mishadoff/tmp/A.class");
    FileInputStream input = new FileInputStream(f);
    byte[] content = new byte[(int)f.length()];
    input.read(content);
    input.close();
    return content;
}

4)、超大数组

    从所周知,常量Integer.MAX_VALUE是JAVA中数组长度的最大值,如果你想创建一个非常大的数组(虽然在通常的应用中不可能会用上),可以通过对内存进行直接分配实现。

    下面这个示例将会创建分配一段连续的内存(数组),它的容易是允许最大容量的两倍。

class SuperArray {
    private final static int BYTE = 1;
    private long size;
    private long address;
     
    public SuperArray(long size) {
        this.size = size;
        //得到分配内存的起始地址
        address = getUnsafe().allocateMemory(size * BYTE);
    }
    public void set(long i, byte value) {
        getUnsafe().putByte(address + i * BYTE, value);
    }
    public int get(long idx) {
        return getUnsafe().getByte(address + idx * BYTE);
    }
    public long size() {
        return size;
    }
}
   应用示例
long SUPER_SIZE = (long)Integer.MAX_VALUE * 2;
SuperArray array = new SuperArray(SUPER_SIZE);
System.out.println("Array size:" + array.size()); // 4294967294
for (int i = 0; i < 100; i++) {
    array.set((long)Integer.MAX_VALUE + i, (byte)3);
    sum += array.get((long)Integer.MAX_VALUE + i);
}
System.out.println("Sum of 100 elements:" + sum);  // 300


但请注意这可能会导致JVM挂掉。

    

    结束语

    sun.misc.Unsafe provides almost unlimited capabilities for exploring and modification of VM’s runtime data structures. Despite the fact that these capabilities are almost inapplicable in Java development itself, Unsafe is a great tool for anyone who want to study HotSpot VM without C++ code debugging or need to create ad hoc profiling instruments.

    sun.misc.Unsafe提供了可以随意查看及修改JVM中运行时的数据结构,尽管这些功能在JAVA开发本身是不适用的,Unsafe是一个用于研究学习HotSpot虚拟机非常棒的工具,因为它不需要调用C++代码,或者需要创建即时分析的工具。


    参考

    http://mishadoff.github.io/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/



转载出处:http://blog.youkuaiyun.com/fenglibing/article/details/17138079

解决升级JDK后:找不到sun.misc.Unsafe的类文件 JDK9以后已经将sun.misc.Unsafe弃用,同时改进了lib文件的存储方式,将sun.misc.Unsafe全部存储在了jdk.unsupported里面。 阅读详情

相关推荐

【java】Java魔法类:Unsafe应用解析

Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。

九师兄 612

sun.misc.unsafe类的使用

Java是一个安全的开发工具,它阻止开发人员犯很多低级的错误,而大部份的错误都是基于内存管理方面的。如果你想搞破坏,可以使用Unsafe这个类。这个类是属于sun.* API中的类,并且它不是J2SE中真正的一部份,因此你可能找不到任何的官方文档,本文介绍Unsafe的非常规使用场景。

冯立彬的博客 4万+

(Touch™)搭建 Windows 开发环境

> OpenHaptics 开发包参考文档。

置心一处,便无事不办 1503

升级springboot2.7+JDK17, 导致:springSecurityFilterChain -- sun.misc.Unsafe.defineClass

升级springboot2.7+JDK17, 导致:springSecurityFilterChain -- sun.misc.Unsafe.defineClass 感觉应该是版本的问题 JAXB能够使用Jackson对JAXB注解的支持实现(jackson-module-jaxb-annotations),既方便生成XML,也方便生成JSON,这样一来可以更好的标志可以转换为JSON对象的JAVA类。

随风飘絮 4192

Android13系统设置第三方app为设备所有者

DevicePolicyManagerService.java文件所在目录是frameworks/base,记得将包类名换成自己app的。2. 将拷贝到系统分区下的两个xml文件继续通过init.rc服务拷贝到data/system/目录下并修改权限。1. 拷贝设备所有者和设备管理器两个对应的xml文件到系统分区。

wzh048503的博客 2509

5G NR 双连接与载波聚合:PCell、SCell、PScell、SpCell 角色全解析

本文全面解析了5G NR中双连接与载波聚合技术的关键概念,详细介绍了PCell、SCell、PScell和SpCell的角色与功能。通过实际案例和配置示例,帮助读者理解这些小区在提升网络覆盖和速率方面的作用,以及在实际组网中的优化策略。

weixin_33220360的博客 375

android java jar日志,java - 在Java Android的Cucumber测试中使用Appium调用UI元素导致构建失败并显示大量日志 - 堆栈内存溢出...

我已经配置了黄瓜测试。 工作正常。我还配置了Appium UI测试,该测试在调用时也可以正常工作。现在,我想在用stepdefinitions文件编写的Cucumber测试下用Appium调用我的活动的UI元素。我的build.gradle// Cucumber for E2E testingandroidTestImplementation 'com.android.support:suppo...

weixin_39638929的博客 558

matlab球面投影(二)

matlab球面投影,想做一个全景相机,不知道,要做成啥样,于是在MATLAB先仿真一下,看下是个啥样子 百度别人做的,复制下面的代码到MATLAB的命令串口下,,网上找了张全景图,可以是bmp,jpg,改程序就可以了 回车运行就可以看到结果。 复制下面代码时,下面的中文注释记得删除,MATLAB是会报错的, close all; clear all; clc [x,y,z]=sphere(50); A=imread('a.JPG'); //名字是自己命名的,记得改 B=warp(x,y,-z,

rjszcb的博客 3165

sun.misc.Unsafe

sun.misc.Unsafe是jdk中为了方便使用java语言灵活操作内存预留的类,由于该类是直接操作内存,所以从java的角度被定义为不安全的,也就是类名的由来。 经常分析jdk源码的同学肯定不陌生,因为jdk中很多地方都用到了这个类。 创建实例:、 sun.misc.Unsafe UNSAFE = sun.misc.Unsafe.getUnsafe() 主要方法如下,本质都是传入一个...

weixin_30799995的博客 187

分布式计算Ray框架面试题及参考答案

动态任务图执行引擎是一种能够根据任务之间的依赖关系和运行时的实际情况,动态构建和执行任务图的系统。在 Ray 中,动态任务图执行引擎允许任务在运行时根据数据可用性、计算资源状态等因素,灵活地决定后续任务的执行顺序和方式。对于 AI 应用来说,其往往具有动态性的特点。例如,在深度学习模型的训练过程中,可能需要根据训练的结果动态调整下一轮训练的参数、数据增强方式或者模型结构。动态任务图执行引擎可以很好地支持这些动态需求。它能够根据 AI 应用中各个任务的实时输出和依赖关系,动态地生成和调整任务图。

大模型大数据攻城狮的专栏 1350

金融领域强化学习在高频交易中的应用

强化学习(Reinforcement Learning,简称RL)是一种机器学习范式,通过智能体与环境的交互来学习策略,以最大化累计奖励。与监督学习和无监督学习不同,强化学习依赖于动态的反馈机制,智能体通过试错不断优化决策过程。高频交易(High-Frequency Trading,简称HFT)是指在极短时间内进行的大量金融交易,通常利用算法和计算机系统自动执行交易策略。高频交易依赖于高速的数据处理和决策能力,以捕捉市场中的微小价格波动。状态(State):环境在某一时刻的观测,反映了系统的当前情况。

AI天才研究院 894

源码剖析之sun.misc.Unsafe

转载于:http://zeige.iteye.com/blog/1182571 首先介绍一下什么是Compare And Swap(CAS)?简单的说就是比较并交换。 CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回

zgmzyr的专栏 8866

056:vue+openlayers 风场快速移动效果(图文代码)

本示例的目的是介绍演示如何在vue+openlayers中使用wind插件来实现风场快速移动的效果。

大剑师兰特的GIS世界 1583

[JUC] sun.misc.Unsafe的原理 【转载】

什么是Unsafe Unsafe类在JDK源码中被广泛使用,在Spark使用off-heap memory时也会使用到,该类功能很强大,涉及到类加载机制,其实例一般情况是获取不到的,源码中的设计是采用单例模式,不是系统加载初始化就会抛出SecurityException异常。 这个类的提供了一些绕开JVM的更底层功能,基于它的实现可以提高效率。(通常是直接操作内存)但是,它是一把双刃剑:正如它的名字所预示的那样,它是Unsafe的,它所分配的内存需要手动free(不被GC回收)。如果对Unsafe类理解

goalietang的专栏 240

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

sun.misc.Unsafe.park(Native Method)

关闭tomcat时或者重启tomcat时 log4j2 报错: sun.misc.Unsafe.park(Native Method) 异常信息: 30-Aug-2018 15:59:34.900 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoader....

2915

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【转载】sun.misc.Unsafe的理解

原文地址:http://www.cnblogs.com/chenpi/p/5389254.html sun.misc.Unsafe的理解 阅读目录 前言Unsafe类的作用获取Unsafe对象 Unsafe类中的API 前言 以下sun.misc.Unsafe源码和demo基于jdk1.7; 最近在看J.U.C里的源码,很多都用到了sun.m

chenshijue的博客 372

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

JDK之sun.misc.Unsafe

//下面是sun.misc.Unsafe.java类源码 package sun.misc; import java.lang.reflect.Field; /*** * This class should provide access to low-level operations and its * use should be limited to trusted code. Field...

长风破浪会有时 1506

『Java安全』Unsafe类

jdk版本基于8u111Unsafe类提供一些低级、不安全的操作,调用前必须确保安全。使用Unsafe可以进行类定义、类实例化、修改内存等操作。绕过安全检查直接向jvm注册类传入六个参数:类名、字节码、字节码起始、字节码长度、加载器、保护域} }

Ho1aAs‘s Blog 1509

Java中的sun.misc.Unsafe

chronicle项目:https://github.com/peter-lawrey/Java-Chronicle 这个项目是利用mmap机制来实现高效的读写数据,号称每秒写入5到20百万条数据。 作者有个测试,写入1百万条log用时0.234秒,用java自带的logger,用时7.347秒。 在看chronicle的源代码,发现一个牛B的利用Unsafe来直接读写内

一些记录 772

Java--如何使用sun.misc.Unsafe完成compareAndSwapObject原子操作

package com; import sun.misc.Unsafe; import java.lang.reflect.Field; /** * Created by yangyu on 16/11/24. */ public class TestUnsafe { public static void main(String[] args) { ...

weixin_30847865的博客 690
上一篇: js解析本地xml文件
下一篇: JAVA并发编程学习笔记之Unsafe类
fantasyagain
博客等级 码龄19年 18粉丝 91原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值