深入Java对象的地址的使用分析
2018-10-12 13:59
639 查看
在传统的Java编程中,你将不再需要从内存中处理Java对象或位置。 当你在论坛上讨论这一点,提出的第一个问题是为什么你需要知道Java对象的地址? 它是一种有效的问题。 但以往,我们保留进行试验的权利。探索未知领域的问题并没有什么错。我想出了一个使用sun公司包的实验。Unsafe是一个属于sun.misc包。对你来说可能这个包有点陌生,看看源代码和方法,你就可以知道我所指的是什么了。
Java的安全管理提供了足够的隐藏来确保你并不能那么容易的摆弄内存。作为第一步,我想到了要得到一个Java对象的内存位置。直到探索,我也曾经是100%的信心,这是不可能找到的位置 Java中对象的地址。
Sun的Unsafe.java API文档显示我们有机会获得地址使用方法objectFieldOffset。这个方法仿佛在说:“报告中的类存储分配它的位置在一个特定领域。“ 它还说,“这只是其中一个访问器的cookie传递给不安全堆内存“。 无论如何,我能够从它的类的存储分配存储一个对象的内存位置。你可以争辩说,我们所得到的是不是一个对象的绝对物理内存地址。但是,我们拿到了逻辑内存地址。下面的程序将受到你的有趣!
作为第一步,我得拿到Unsafe类的一个对象。这是很困难的,因为构造函数是私有的。 有一个名为getUnsafe一个方法,该方法返回不安全的对象。Java安全管理要求您给源代码特权。我用到了一点反射然后得到了一个实例。我知道有更好的方法来获得实例,但我选择了以下的方法来绕开安全管理。
使用Unsafe的对象,只需要调用objectFieldOffset和staticFieldOffset。结果就是类的内存分配地址。
以下的实例程序可以运行在JDK1.6上。
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class ObjectLocation {
private static int apple = 10;
private int orange = 10;
public static void main(String[] args) throws Exception {
Unsafe unsafe = getUnsafeInstance();
Field appleField = ObjectLocation.class.getDeclaredField("apple");
System.out.println("Location of Apple: "
+ unsafe.staticFieldOffset(appleField));
Field orangeField = ObjectLocation.class.getDeclaredField("orange");
System.out.println("Location of Orange: "
+ unsafe.objectFieldOffset(orangeField));
}
private static Unsafe getUnsafeInstance() throws SecurityException,
NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (Unsafe) theUnsafeInstance.get(Unsafe.class);
}
}
API介绍:
boolean compareAndSwapInt(Object obj,long fieldoffset, int expect, int update);
修改 obj对象的(fieldoffset)Int 属性值,若属性值为expect,则修改为 update ,返回true,若属性值不为expect则不修改,返回false
boolean compareAndSwapObject(Object obj,long Fieldoffset, Object expect, Object update);
修改 obj对象的(fieldoffset)属性值,若属性值为expect,则修改为 update ,返回true,若属性值不为expect则不修改,返回false
long objectFieldOffset (Field field);
得到 filed在对象中的偏移
void park(boolean flag, long time);
使当前线程等待
void unpark(Thread thread)
使当前线程停止等待
Object getObject(Object obj,long fieldoffset);
得到 obj 的 偏移为fieldoffset 的属性
int getInt(Object obj,long fieldoffset);
得到 obj 的 偏移为fieldoffset 的int属性
您可能感兴趣的文章:
相关文章推荐
- 深入分析使用mysql_fetch_object()以对象的形式返回查询结果
- 使用sun.misc.Unsafe获取java对象地址
- JAVA 反射机制 在运行时使用反射分析对象
- 使用sun.misc.Unsafe获取java对象地址
- JAVA随笔篇二(深入分析JAVA简单类型、String和对象的值传递和引用传递)
- 深入分析Java使用+和StringBuilder进行字符串拼接的差异
- 深入分析Java内存区域的使用详解
- 深入分析JavaWeb Item28 -- 使用JDBC对数据库进行CRUD
- 深入分析虚拟机在Java堆中对象分配、布局和访问的全过程
- 深入java面向对象四:Java 内部类种类及使用解析(转)
- Java之对象的创建和使用的一个实例分析
- 深入分析Java对象的建构顺序
- 深入分析JavaWeb 3 -- Tomcat服务器学习和使用2
- 深入分析JS原型链以及为什么不能在原型链上使用对象
- 深入分析JS原型链以及为什么不能在原型链上使用对象
- Java中引用变量的使用_传引用就是传地址。因为"传地址数值"比"传对象的拷贝" 简单 。
- 深入分析Java对象的建构顺序
- 深入分析Java使用+和StringBuilder进行字符串拼接的差异
- 深入分析Java对象的建构顺序
- Spring: 读取 .properties 文件地址,json转java对象,el使用java类方法相关 (十三)