欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-02-10 15:11:34
 在传统的java编程中,你将不再需要从内存中处理java对象或位置。 当你在论坛上讨论这一点,提出的第一个问题是为什么你需要知道java对象的地址? 它是一种有...

 在传统的java编程中,你将不再需要从内存中处理java对象或位置。 当你在论坛上讨论这一点,提出的第一个问题是为什么你需要知道java对象的地址? 它是一种有效的问题。 但以往,我们保留进行试验的权利。探索未知领域的问题并没有什么错。我想出了一个使用sun公司包的实验。unsafe是一个属于sun.misc包。对你来说可能这个包有点陌生,看看源代码和方法,你就可以知道我所指的是什么了。

java的安全管理提供了足够的隐藏来确保你并不能那么容易的摆弄内存。作为第一步,我想到了要得到一个java对象的内存位置。直到探索,我也曾经是100%的信心,这是不可能找到的位置 java中对象的地址。
深入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属性