深入Java对象的地址的使用分析
在传统的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数据库基础命令大全(收藏)
推荐阅读
-
深入Java对象的地址的使用分析
-
使用谷歌Gson实现Json数据与Java对象、List、Map之间的相互转换笔记
-
使用JDK自带的VisualVM进行Java程序的性能分析 JDKVisualVM性能分析
-
Java~反射的API文档使用(利用反射创建对象、反射私有构造方法、反射私有属性、反射私有方法)
-
node.js Promise对象的使用方法实例分析
-
java工厂模式 PHP高级对象构建 工厂模式的使用
-
深入分析使用mysql_fetch_object()以对象的形式返回查询结果
-
为什么数据分析一般用到java,而不是使用hadoop,flume,hive的api使用php来处理相关业务?
-
为什么数据分析一般用到java,而不是使用hadoop,flume,hive的api使用php来处理相关业务?
-
记一次使用JAVA上转型对象出现的问题