>tree . /F
Folder PATH listing for volume D
Volume serial number is F075-351A
└───com
└───jx
com_jx_Object.cpp
com_jx_Object.hpp
com_jx_Object.obj
libobj.dll
libobj.exp
libobj.lib
Object.class
Object.java
ObjectTest.java
package com.jx; public class Object { private int index; public Object(int index) { this.index = index; } public int index() { return index; } public native int addr(); static { System.loadLibrary("libobj"); } }
>javac com\jx\Object.java
>javah -jni -d com\jx com.jx.Object
com_jx_Object.hpp:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_jx_Object */ #ifndef _Included_com_jx_Object #define _Included_com_jx_Object #ifdef __cplusplus extern "C" { #endif /* * Class: com_jx_Object * Method: addr * Signature: ()I */ JNIEXPORT jint JNICALL Java_com_jx_Object_addr (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
com_jx_Object.cpp:
#include <stdio.h> #include "com_jx_Object.hpp" JNIEXPORT jint JNICALL Java_com_jx_Object_addr (JNIEnv *env, jobject jobj) { jlong addr = reinterpret_cast<jlong>(jobj); printf("Java_com_jx_Object_addr.\n"); printf("obj addr: %ld\n", jobj); printf("obj addr: %ld\n", &jobj); printf("obj addr: %ld\n", addr); return 0; }
上面的jobj(jobject类型,表示JNI pointer,或JNI指针)实际上是Java对象对应的oop类型指针(oop *,它指向Java对象对应的oop)的地址。
代码如下:
Java:
A a;
在jvm中,
oop* ptr = (oop *)jobj;
通过reinterpret_cast类型转换得到的是ptr指针本身的地址。所以它和jobj指向的是同一地址。
>cl /GR /GX /W3 /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /c /Fo.\ *.cpp
>link /DLL /OUT:.\libobj.dll .\*.obj
也可以使用以下命令一次就生成库文件
# 也可以使用以下命令一次就生成库文件: >cl /ID:\usr\bin\jdk1.8.0_101\include /ID:\usr\bin\jdk1.8.0_101\include\win32 /LD com_jx_Object.c
将生成的库文件libobj.dll放在path目录下
package com.jx; import java.lang.reflect.Field; import sun.misc.Unsafe; public class ObjectTest { public static void main(String[] args) throws Throwable { String libPath = System.getProperty("java.library.path"); System.out.println(libPath); Unsafe unsafe = getUnsafe(); Object obj = new Object(12345); Field field = Object.class.getDeclaredField("index"); long addr = location(obj); System.out.println("obj addr: " + obj.hashCode()); System.out.println("obj addr: " + addr); System.out.println("obj addr: " + unsafe.getAddress(addr)); long valueOffset = unsafe.objectFieldOffset(field); System.out.println("index offset: " + valueOffset); int value2 = unsafe.getInt(obj, valueOffset); System.out.println("index: " + value2); value2 = unsafe.getInt(addr + valueOffset); System.out.println("index: " + value2); obj.addr(); } public static long location(Object object) throws Throwable { Unsafe unsafe = getUnsafe(); Object[] array = new Object[] {object}; long baseOffset = unsafe.arrayBaseOffset(Object[].class); int addressSize = unsafe.addressSize(); long location; switch (addressSize) { case 4: location = unsafe.getInt(array, baseOffset); break; case 8: location = unsafe.getLong(array, baseOffset); break; default: throw new Error("unsupported address size: " + addressSize); } return (location); } private static Unsafe getUnsafe() throws Throwable { Class unsafeClass = Unsafe.class; for (Field f : unsafeClass.getDeclaredFields()) { if ("theUnsafe".equals(f.getName())) { f.setAccessible(true); return (Unsafe) f.get(null); } } throw new IllegalAccessException("no declared field: theUnsafe"); } }
运行结果
obj addr: 5433634 obj addr: 46840104 obj addr: 695505153 index offset: 8 index: 12345 index: 12345 Java_com_jx_Object_addr. obj addr: 10157232 obj addr: 10157172 obj addr: 10157232
在上面例子中,Unsafe getAddress返回的是obj对应内存地址的本地指针(native pointer)。
相关推荐
本文将详细探讨Java对象在JVM中的创建过程以及其内存布局,帮助读者更深入地理解Java对象是如何在内存中产生的。 #### 二、对象的创建 Java对象是由类实例化的结果,当我们使用`new`关键字创建一个对象时,实际上...
### Java中对象与引用 在Java编程中,深入理解对象与引用的概念对于掌握面向对象编程至关重要。本文将从以下几个方面详细解析对象与引用的基本概念及其相互间的关系。 #### 一、对象与引用的基础概念 **对象**: ...
引用变量存储的是对象的内存地址。当一个对象被引用变量引用时,我们可以通过这个引用变量来操作对象。this关键字则用于引用类的当前实例,通常用于区分成员变量和局部变量。 下面,我们逐一解析提供的练习题: 1....
在Java编程中,获取IP地址是一项常见的任务,特别是在网络编程和服务器开发中。这个"java IP地址工具类"是为了解决这个问题而设计的。它提供了便捷的方法来获取和处理IP地址,尤其对于获取客户端IP地址在Web应用中至...
本篇文章将深入探讨Java对象在JVM内存中的布局,帮助我们理解JVM是如何存储和管理对象的。 首先,我们要知道JVM内存主要分为以下几个区域: 1. **堆内存(Heap)**:这是Java对象的主要存储区域,所有通过`new`...
在Java编程环境中,实现IPv6地址查询涉及到网络编程和数据库操作。IPv6是互联网协议的第六版,相较...通过理解IPv6地址的结构,掌握ZX公网IPv6库的API,并熟练运用Java面向对象编程,可以构建出高效、可靠的查询系统。
Java对象在内存中的结构及其生命周期是Java编程中基础且关键的概念。Java的内存管理主要涉及栈(Stack)和堆(Heap)两个区域,对于理解程序的性能和内存使用至关重要。 首先,栈主要用于存储基本数据类型(如int, ...
在Java中,“=”符号并不意味着两个对象之间的赋值,而是一个指向对象地址的传递。例如: ```java A a3 = new A(); A a4 = new A(); a3 = a4; // 此时a3和a4都指向同一个由new A()创建的对象 ``` 这里需要...
#### 一、Java对象、引用及创建过程 在Java中,对象是程序的基本单位,它包含了属性(成员变量)和行为(方法)。对象是由类创建出来的实例,而类则是一组具有相同属性和行为的对象的模板。 ##### 1. 对象创建与...
Java对象池化技术是一种优化程序性能的策略,它通过预先创建一组对象并保留它们,以便在需要时重复使用,而不是每次需要时都创建新的对象。这样可以显著减少对象的创建和初始化时间,尤其适用于那些创建成本较高的...
// 深克隆地址对象 return clonedPerson; } } public class Address implements Cloneable { private String city; private String country; // getters and setters @Override protected Object clone()...
### Java内存对象分配过程研究 #### 一、引言 Java作为一门强大的面向对象编程语言,在实际开发过程中,对象的创建及其内存管理是至关重要的环节。深入理解对象在内存中的分配过程不仅能够帮助开发者设计出更为...
完整版 Java基础入门教程 Java程序语言设计 03 java对象 集合框架(共18页).ppt 完整版 Java基础入门教程 Java程序语言设计 03 java对象 类和对象1(共23页).ppt 完整版 Java基础入门教程 Java程序语言设计 03 ...
完整版 Java基础入门教程 Java程序语言设计 03 java对象 集合框架(共18页).ppt 完整版 Java基础入门教程 Java程序语言设计 03 java对象 类和对象1(共23页).ppt 完整版 Java基础入门教程 Java程序语言设计 03 ...
完整版 Java基础入门教程 Java程序语言设计 03 java对象 集合框架(共18页).ppt 完整版 Java基础入门教程 Java程序语言设计 03 java对象 类和对象1(共23页).ppt 完整版 Java基础入门教程 Java程序语言设计 03 ...
基本类型数据是按值传递,而对象是按引用传递,这意味着传递的是对象在内存中的地址,而不是对象本身。 **static关键字**: - `static`修饰的成员属于类,不依赖于类的实例。这意味着静态变量和静态方法是所有对象...
Java 面向对象基础知识点 Java 是一门面向对象的编程语言,面向对象编程(Object-Oriented Programming,OOP)是 Java 语言的核心。了解 Java 面向对象的基础知识是掌握 Java 语言的关键,本文将对 Java 面向对象的...
### Java对象和对象的引用之间的关系 #### 一、Java对象和对象的引用的基本概念 在Java编程语言中,理解对象和对象引用之间的关系是非常重要的基础。对象是类的一个实例,而对象引用则是用于访问该对象的一种手段...
- 将堆内存中的对象地址赋值给引用变量。 #### 十、匿名对象 匿名对象是没有名字的对象,它通常用于只需要调用对象一次的情况。匿名对象的生命周期很短,一旦方法执行完毕,匿名对象就会失去引用,成为垃圾收集的...