并行编程(2) - sum.msic.Unsafe 二

整理了几个以前从网上记录sum.msic.Unsafe类的示例,供大家参考:

package com.fish.unsafe;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import sun.misc.Unsafe;

/**
 * @version 1.0
 * @author Fish
 */
public class UnsafeTest {
	public static Unsafe unsafe;

	@Before
	public void init() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		// 通过反射获取rt.jar下的Unsafe类
		Field field = Unsafe.class.getDeclaredField("theUnsafe");
		field.setAccessible(true);
		unsafe = (Unsafe) field.get(null);
	}

	/**
	 * allocateInstance初始化对象不调用构造方法
	 *
	 * @Description:
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @author Fish
	 * @date 2015年6月24日
	 */
	@Test
	public void testAllocateInstance() throws InstantiationException, IllegalAccessException {
		UnsafeClass un = new UnsafeClass(); // constructor
		System.out.println(un.a()); // prints 1
		UnsafeClass uu2 = UnsafeClass.class.newInstance(); // reflection
		System.out.println(uu2.a()); // prints 1
		UnsafeClass uu3 = (UnsafeClass) unsafe.allocateInstance(UnsafeClass.class); // unsafe
		System.out.println(uu3.a());// prints 0
	}

	/**
	 * 修改private变量的值
	 *
	 * @Description:
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 * @author Fish
	 * @date 2015年6月24日
	 */
	@Test
	public void testObjectFieldOffset() {
		try {
			UnsafeClass un = new UnsafeClass();
			System.out.println(un.isEqual());
			Field f = un.getClass().getDeclaredField("a");
			unsafe.putInt(un, unsafe.objectFieldOffset(f), 42); // memory
			System.out.println(un.isEqual()); // true, access granted
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 获取对象的大小
	 * @Description:
	 * @author Fish
	 * @date 2015年6月24日
	 */
	@Test
	public void testSizeof() {
		UnsafeClass un = new UnsafeClass();
		System.out.println(sizeOf1(un));
	}

	public static long sizeOf1(Object object) {
		HashSet<Field> fields = new HashSet<Field>();
		Class<?> c = object.getClass();
		while (c != Object.class) {
			for (Field f : c.getDeclaredFields()) {
				if ((f.getModifiers() & Modifier.STATIC) == 0) {
					fields.add(f);
				}
			}
			c = c.getSuperclass();
		}
		// get offset
		long maxSize = 0;
		for (Field f : fields) {
			long offset = unsafe.objectFieldOffset(f);
			if (offset > maxSize) {
				maxSize = offset;
			}
		}
		return ((maxSize / 8) + 1) * 8; // padding
	}

	/**
	 * 浅拷贝:该方法可以用来拷贝任何类型的对象,动态计算它的大小。
	 *
	 * @Description:
	 * @author Fish
	 * @date 2015年6月24日
	 */
	@Test
	public void testShallowCopy() {
		List<String> list = new ArrayList<String>();
		list.add("123A");
		list.add("123B");
		list.add("123C");
		long size = sizeOf1(list);
		long start = toAddress(list);
		long address = unsafe.allocateMemory(size);
		unsafe.copyMemory(start, address, size);
		System.out.println(fromAddress(address));
	}

	private static long normalize(int value) {
		if (value >= 0)
			return value;
		return (~0L >>> 32) & value;
	}

	public static long toAddress(Object obj) {
		Object[] array = new Object[] { obj };
		long baseOffset = unsafe.arrayBaseOffset(Object[].class);
		return normalize(unsafe.getInt(array, baseOffset));
	}

	static Object fromAddress(long address) {
		Object[] array = new Object[] { null };
		long baseOffset = unsafe.arrayBaseOffset(Object[].class);
		unsafe.putLong(array, baseOffset, address);
		return array[0];
	}

	/**
	 * 密码隐藏:通常我们会将用完的密码设置为null,但是在设置为null到GC垃圾回收该对象,是有一定的时间。在这段时间内,该对象还存在于内存中,
	 * 就在这段时间内,很可能被黑客利用
	 *
	 * @Description:
	 * @author Fish
	 * @date 2015年6月24日
	 */
	@Test
	public void testPassword() {
		String password = new String("[email protected]$e");
		String fake = new String(password.replaceAll(".", "?"));
		System.out.println(password); // [email protected]$e
		System.out.println(fake); // ????????????
		unsafe.copyMemory(fake, 0L, null, toAddress(password), sizeOf1(password));
		System.out.println(password); // ????????????
		System.out.println(fake); // ????????????
	}

	 /**
	 * 动态创建类
	 * @Description:
	 * @author Fish
	 * @date 2015年6月24日
	 */
	 @Test
	 public void testDynamicClasses() {
		 try {
			 File f = new File("D:\\A.class");
			 FileInputStream input = new FileInputStream(f);
			 byte[] content = new byte[(int) f.length()];
			 input.read(content);
			 input.close();
                         <span style="color:#FF0000;">// unsafe.defineClass(null, content, 0, content.length);该方法在JDK8找不到</span>
                         Class<?> c = unsafe.defineClass(null, content, 0, content.length);
			 c.getMethod("a").invoke(c.newInstance(), null); // 1
		 } catch (FileNotFoundException e) {
			 e.printStackTrace();
		 } catch (IOException e) {
			 e.printStackTrace();
		 }
	 }

	/**
	 * 大数组:这种方式的内存分配不在堆上,且不受GC管理,所以必须小心Unsafe.freeMemory()的使用
	 * @Description:
	 * @author Fish
	 * @date 2015年6月24日
	 */
	@Test
	public void testBigArray() {
		long SUPER_SIZE = (long) Integer.MAX_VALUE * 2;
		SuperArray array = new SuperArray(SUPER_SIZE);
		System.out.println("Array size:" + array.size()); // 4294967294
		int sum = 0;
		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
	}

}

class SuperArray {
	private final static int BYTE = 1;

	private long size;

	private long address;

	public SuperArray(long size) {
		this.size = size;
		address = UnsafeTest.unsafe.allocateMemory(size * BYTE);
	}

	public void set(long i, byte value) {
		UnsafeTest.unsafe.putByte(address + i * BYTE, value);
	}

	public int get(long idx) {
		return UnsafeTest.unsafe.getByte(address + idx * BYTE);
	}

	public long size() {
		return size;
	}
}

class UnsafeClass {
	private long a;

	public UnsafeClass() {
		this.a = 1;
	}

	public long a() {
		return this.a;
	}

	public boolean isEqual() {
		return 42 == a;
	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-14 18:41:51

并行编程(2) - sum.msic.Unsafe 二的相关文章

并行编程(1) - sum.msic.Unsafe 一

相信看过java源代码的同学.对 sum.msic.Unsafe 这个类并不陌生,特别是在java.util.concurrent包有非常多的使用. sum.msic.Unsafe源代码:      http://www.docjar.com/html/api/sun/misc/Unsafe.java.html javadoc:      http://www.docjar.com/docs/api/sun/misc/Unsafe.html sum.msic.Unsafe是一个运行低级别(硬件级

并行编程和任务(二)

前言 上一篇我们主要介绍了并行编程相关的知识,这一节我们继续介绍关于任务相关的知识.为了更好的控制并行操作,我们可以使用System.Threading.Tasks中的Task类.我们首先来了解是什么是任务——任务表示将要完成的一个或某个工作单元,这个工作单元可以在单独线程中运行,也可以使用同步方式启动运行(需要等待主线程调用).为什么使用任务呢?——任务不仅可以获得一个抽象层(将要完成的工作单元).还可以对底层的线程运行进行更好更多的控制(任务的运行). 使用线程池的任务 我们讲到使用任务可以

OpenCL学习笔记(二):并行编程概念理解

欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术.应用感兴趣的同学加入. 并行编程的需求是显而易见的,其最大的难题是找到算法的并行功能,同时必须处理数据的共享和同步.但是,因为每一个算法都是不一样的,很难有通用的并行功能--粒度都有可能是不一样的.OpenCL提供了很多并行的抽象模型,因此算法开发人员可以在不同粒度上开发并行的算法,以及数据的共享和同步. 一般来说,并行编程有两种大类型--分散收集(s

OpenMP 并行编程

最近开始学习并行编程,目的是为了提高图像处理的运行速度,用的是VS2012自带的OpenMP. 如何让自己的编译器支持OpenMP: 1) 点击 项目属性页 2)点击 配置 3)点击 [C/C++] 4)点击 语言 5)选中OpenMP支持 OpenMP 的构成:编译器指令 + 运行时例程: 编译器指令: 以 #pragma omp 开头,用以告知编译器哪一段代码需要并行. 运行时例程:必须包括omp.h 设置和获取执行环境相关的信息,也包括一系列用以同步的API: 编译器指令格式如下: #pr

C#中的多线程 - 并行编程 z

原文:http://www.albahari.com/threading/part5.aspx 专题:C#中的多线程 1并行编程Permalink 在这一部分,我们讨论 Framework 4.0 加入的多线程 API,它们可以充分利用多核处理器. 并行 LINQ(Parallel LINQ)或称为 PLINQ Parallel类 任务并行(task parallelism)构造 SpinLock 和 SpinWait 这些 API 可以统称为 PFX(Parallel Framework,并行

并行编程入门

目录 1. 并行编程简介 2. MapReduce 2.1 MapReduce简介 2.2 MapReduce框架 2.3 Hadoop介绍 2.4 Hadoop基本类 2.5 Hadoop编程实例 1.并行编程简介 1.1.并行编程作用,用途 商业用途,科学计算,大数据分析 1.2.并行编程兴起原因 目前的串行编程的局限性 使用的流水线等隐式并行模式的局限性 硬件的发展 1.3.并行算法设计原则步骤 a.分析问题 b.分解问题 其中分解方法有: 数据分解 递归分解 探测性分解 推测性分解 混合

五 浅谈CPU 并行编程和 GPU 并行编程的区别

前言 CPU 的并行编程技术,也是高性能计算中的热点,也是今后要努力学习的方向.那么它和 GPU 并行编程有何区别呢? 本文将做出详细的对比,分析各自的特点,为将来深入学习 CPU 并行编程技术打下铺垫. 区别一:缓存管理方式的不同 GPU:缓存对程序员不透明,程序员可根据实际情况操纵大部分缓存 (也有一部分缓存是由硬件自行管理). CPU:缓存对程序员透明.应用程序员无法通过编程手段操纵缓存. 区别二:指令模型的不同 GPU:采用 SIMT - 单指令多线程模型,一条指令配备一组硬件,对应32

Net并行编程高级教程--Parallel

Net并行编程高级教程--Parallel 一直觉得自己对并发了解不够深入,特别是看了<代码整洁之道>觉得自己有必要好好学学并发编程,因为性能也是衡量代码整洁的一大标准.而且在<失控>这本书中也多次提到并发,不管是计算机还是生物都并发处理着各种事物.人真是奇怪,当你关注一个事情的时候,你会发现周围的事物中就常出现那个事情.所以好奇心驱使下学习并发.便有了此文. 一.理解硬件线程和软件线程 多核处理器带有一个以上的物理内核--物理内核是真正的独立处理单元,多个物理内核使得多条指令能够

.Net中的并行编程-6.常用优化策略

            本文是.Net中的并行编程第六篇,今天就介绍一些我在实际项目中的一些常用优化策略.      一.避免线程之间共享数据 避免线程之间共享数据主要是因为锁的问题,无论什么粒度的锁,最好的线程之间同步方式就是不加锁,这个地方主要措施就是找出数据之间的哪个地方需要共享数据和不需要共享数据的地方,再设计上避免多线程之间共享数据. 在以前做过的某项目,开始时设计的方案: 开始设计时所有的数据都放入到了公共队列,然后队列通知多个线程去处理数据,队列采用互斥锁保证线程同步,造成的结果就