|
|
@@ -0,0 +1,235 @@
|
|
|
+package space.anyi.jni.reference;
|
|
|
+
|
|
|
+import java.util.Objects;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @ProjectName: JNI_learn
|
|
|
+ * @FileName: Main
|
|
|
+ * @Author: 杨逸
|
|
|
+ * @Data:2026/3/4 21:25
|
|
|
+ * @Description:
|
|
|
+ */
|
|
|
+public class Main {
|
|
|
+ static {
|
|
|
+ System.load("E:\\tmp\\JNI_learn\\c\\reference\\JNI_globalReference.dll");
|
|
|
+ System.load("E:\\tmp\\JNI_learn\\c\\reference\\JNI_weakGlobalReference.dll");
|
|
|
+ System.load("E:\\tmp\\JNI_learn\\c\\reference\\JNI_localReference.dll");
|
|
|
+ }
|
|
|
+ public static void main(String[] args) {
|
|
|
+ //GlobalReferenceTest.test();
|
|
|
+ //WeakGlobalReferenceTest.testJVMGC();
|
|
|
+ LocalReferenceTest.test();
|
|
|
+ }
|
|
|
+}
|
|
|
+class LocalReferenceTest{
|
|
|
+ static LocalReferenceTest localReferenceTest = new LocalReferenceTest();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试在JVM中使用JNI创建的对象局部引用
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/05 21:06:10
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ static void test(){
|
|
|
+ Person person = localReferenceTest.getPerson();
|
|
|
+ System.gc();
|
|
|
+ try {
|
|
|
+ Thread.sleep(1000*5);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ System.out.println(Objects.isNull(person));
|
|
|
+ System.out.println("person = " + person);
|
|
|
+ }
|
|
|
+ static void testJVMGC(){
|
|
|
+ while (true){
|
|
|
+ localReferenceTest.getPerson();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 在JNI中创建一个局部引用,并返回对象
|
|
|
+ * @return {@code Person }
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/05 22:35:30
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ native Person getPerson();
|
|
|
+}
|
|
|
+class GlobalReferenceTest{
|
|
|
+ static GlobalReferenceTest globalReferenceTest = new GlobalReferenceTest();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试在JVM中使用JNI创建的对象全局引用
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/05 21:06:10
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ static void test(){
|
|
|
+ //获取全局引用的句柄
|
|
|
+ long personHandler = globalReferenceTest.getPersonHandler();
|
|
|
+
|
|
|
+ //根据句柄获取全局引用对象
|
|
|
+ Person person = globalReferenceTest.getPerson(personHandler);
|
|
|
+ System.out.println("person.getName() = " + person.getName());
|
|
|
+ System.out.println("person.getAge() = " + person.getAge());
|
|
|
+ System.out.println(person);
|
|
|
+ //释放全局引用
|
|
|
+ globalReferenceTest.freePerson(personHandler);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试JNI创建的对象全局引用是否会被JVM垃圾回收
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/05 21:06:34
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ static void testJVMGC(){
|
|
|
+ //获取全局引用的句柄
|
|
|
+ long personHandler = globalReferenceTest.getPersonHandler();
|
|
|
+ //根据句柄获取全局引用对象
|
|
|
+ Person person = globalReferenceTest.getPerson(personHandler);
|
|
|
+ System.gc();
|
|
|
+ try {
|
|
|
+ Thread.sleep(1000*5);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ while (true){
|
|
|
+ globalReferenceTest.getPersonHandler();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 在JNI中创建一个全局引用,并返回句柄
|
|
|
+ * @return long 全局引用的句柄
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/04 21:29:12
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ native long getPersonHandler();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据句柄获取全局引用对象
|
|
|
+ * @param handler 句柄
|
|
|
+ * @return {@code Person } 全局引用对象
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/04 21:30:09
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ native Person getPerson(long handler);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 释放JNI创建的全局引用
|
|
|
+ * @param handler 句柄
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/04 21:30:38
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ native void freePerson(long handler);
|
|
|
+}
|
|
|
+class WeakGlobalReferenceTest {
|
|
|
+ static WeakGlobalReferenceTest globalWeakReferenceTest = new WeakGlobalReferenceTest();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试在JVM中使用JNI创建的对象全局弱引用
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/05 21:06:10
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ static void test(){
|
|
|
+ //获取全局弱引用的句柄
|
|
|
+ long personHandler = globalWeakReferenceTest.getPersonHandler();
|
|
|
+
|
|
|
+ //根据句柄获取全局引用对象
|
|
|
+ Person person = globalWeakReferenceTest.getPerson(personHandler);
|
|
|
+ System.out.println("person.getName() = " + person.getName());
|
|
|
+ System.out.println("person.getAge() = " + person.getAge());
|
|
|
+ System.out.println(person);
|
|
|
+ //释放全局弱引用
|
|
|
+ globalWeakReferenceTest.freePerson(personHandler);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试JNI创建的对象全局引用是否会被JVM垃圾回收
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/05 21:06:34
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ static void testJVMGC(){
|
|
|
+ while (true){
|
|
|
+ globalWeakReferenceTest.getPersonHandler();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 在JNI中创建一个全局引用,并返回句柄
|
|
|
+ * @return long 全局弱引用的句柄
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/04 21:29:12
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ native long getPersonHandler();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据句柄获取全局弱引用对象
|
|
|
+ * @param handler 句柄
|
|
|
+ * @return {@code Person } 全局引用弱对象
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/04 21:30:09
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ native Person getPerson(long handler);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 释放JNI创建的全局弱引用
|
|
|
+ * @param handler 句柄
|
|
|
+ * @description:
|
|
|
+ * @author: 杨逸
|
|
|
+ * @data:2026/03/04 21:30:38
|
|
|
+ * @since 1.0.0
|
|
|
+ */
|
|
|
+ native void freePerson(long handler);
|
|
|
+}
|
|
|
+class Person{
|
|
|
+ private String name;
|
|
|
+ private int age;
|
|
|
+
|
|
|
+ public Person(String name, int age) {
|
|
|
+ this.name = name;
|
|
|
+ this.age = age;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getName() {
|
|
|
+ return name;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setName(String name) {
|
|
|
+ this.name = name;
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getAge() {
|
|
|
+ return age;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setAge(int age) {
|
|
|
+ this.age = age;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String toString() {
|
|
|
+ return "Person{" +
|
|
|
+ "name='" + name + '\'' +
|
|
|
+ ", age=" + age +
|
|
|
+ '}';
|
|
|
+ }
|
|
|
+}
|