深入Java对象的地址的使用分析

所属分类: 软件编程 / java 阅读数: 84
收藏 0 赞 0 分享

 在传统的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属性

更多精彩内容其他人还在看

Spring boot将配置属性注入到bean类中

本篇文章主要介绍了Spring boot将配置属性注入到bean类中,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Java正则判断日期格式是否正确的方法示例

这篇文章主要介绍了Java正则判断日期格式是否正确的方法,结合实例形式分析了Java针对日期字符串正则判断的相关操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

java Future 接口使用方法详解

这篇文章主要介绍了java Future 接口使用方法详解,Future接口是Java线程Future模式的实现,可以来进行异步计算的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Java 读取外部资源的方法详解及实例代码

这篇文章主要介绍了Java 读取外部资源的方法详解及实例代码的相关资料,经常有读取外部资源的要求,如配置文件等等需要读取,需要的朋友可以参考下
收藏 0 赞 0 分享

Java正则表达式之split()方法实例详解

这篇文章主要介绍了Java正则表达式之split()方法,结合实例形式较为详细的分析了split方法的功能、使用方法及相关注意事项,需要的朋友可以参考下
收藏 0 赞 0 分享

Java 存储模型和共享对象详解

这篇文章主要介绍了Java 存储模型和共享对象详解的相关资料,对Java存储模型,可见性和安全发布的问题是起源于Java的存储结构及共享对象安全,需要的朋友可以参考下
收藏 0 赞 0 分享

Java使用正则表达式实现找出数字功能示例

这篇文章主要介绍了Java使用正则表达式实现找出数字功能,结合实例形式分析了Java针对数字的匹配查找及非数字替换操作相关实现技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

Spring核心IoC和AOP的理解

本文主要介绍了Spring核心IoC和AOP的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧
收藏 0 赞 0 分享

详解Spring AOP 拦截器的基本实现

本篇文章主要介绍了详解Spring AOP 拦截器的基本实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Mybatis 中的一对一,一对多,多对多的配置原则示例代码

这篇文章主要介绍了 Mybatis 中的一对一,一对多,多对多的配置原则示例代码,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多