我必须DeleteLocalRef一个我调用NewGlobalRef的对象吗?

时间:2015-06-09 01:31:21

标签: java java-native-interface

众所周知,在C / C ++拥有的线程中创建Java对象,我们有责任根据需要调用Running Sum: Over AllDeleteLocalRef

我有一些像

这样的代码
Push/Pop LocalFrame

本机代码创建一个字节数组,它在多个线程/调用中重复使用,一旦我们完成它,我在缓冲区上调用jbyteArray buffer = env->NewByteArray((jsize)requiredSize); longTermBufferReference = (jbyteArray)env->NewGlobalRef(buffer);

问题是,当我完成时,我必须在DeleteGlobalRef上调用DeleteLocalRef,或者GlobalRef是否完全拥有该对象?

3 个答案:

答案 0 :(得分:3)

在垃圾收集系统中,没有对象所有权这样的东西。有根对象引用和对象引用可以直接或间接从根进行访问。 (不考虑弱引用)。

JNI本地引用和JNI全局引用都是根引用。创建其他引用不会影响现有引用,也不会从根引用列表中删除它们。

所以,是的,必须删除本地引用(就像必须删除全局引用一样)。您已经知道可以使用DeleteLocalRefPopLocalFrame显式执行此操作,或者,当JNI本机方法返回时,JNI会自动有效地调用PopLocalFrame

答案 1 :(得分:0)

  

问题是,当我完成

时,我必须在缓冲区上调用DeleteLocalRef

不,您可以在JNI方法返回时自动将其删除,如果您使用,则可以 var etjoin = from e in ExcelData.AsEnumerable() join t in TstarData.AsEnumerable() on e.Field<String>("IP Address") equals t.Field<String>("UserDefinedColumn3") into leftjointable from x in leftjointable.DefaultIfEmpty() select new { TS_IP = x.Field<String>("UserDefinedColumn3") != null ? x.Field<String>("UserDefinedColumn3") : "xxxxxx", TS_VehicleName = x.Field<String>("VehicleName") != null ? x.Field<String>("VehicleName") : "xxxxxx", TS_VehicleGroupName = x.Field<String>("VehicleGroupName") != null ? x.Field<String>("VehicleGroupName") : "xxxxxx", TS_Phone = x.Field<String>("UserDefinedColumn2") != null ? x.Field<String>("UserDefinedColumn2") : "xxxxxx", EX_IP = e.Field<String>("IP Address") != null ? e.Field<String>("IP Address") : "xxxxxx", EX_ICCID = e.Field<String>("ICCID") != null ? e.Field<String>("ICCID") : "xxxxxx", EX_Status = e.Field<String>("SIM Status") != null ? e.Field<String>("SIM Status") : "xxxxxx", Ex_Session = e.Field<String>("In Session") != null ? e.Field<String>("In Session") : "xxxxxx", Ex_Activated = e.Field<String>("Activated") != null ? e.Field<String>("Activated") : "xxxxxx" }; // use ? operator on all columns to return empty string or something var fulljoin = from e in etjoin join m in M5Data.AsEnumerable() on e.TS_VehicleName equals m.Field<String>("Unit_No") into leftjointable from x in leftjointable.DefaultIfEmpty() select new { TS_IP = e.TS_IP, TS_VehicleName = e.TS_VehicleName, TS_VehicleGroupName = e.TS_VehicleGroupName, TS_Phone = e.TS_Phone, EX_IP = e.EX_IP, EX_ICCID = e.EX_ICCID, EX_Status = e.EX_Status, EX_Session = e.Ex_Session, Ex_Session = e.EX_Status, M5_Unit_No = x.Field<String>("Unit_No"), M5_Unit_ID = x.Field<String>("Unit_ID"), M5_Using_Dept = x.Field<String>("Using_Dept"), M5_Status = x.Field<String>("Status"), M5_Using_Dept_Desc = x.Field<String>("Using_Dept_Desc"), M5_Most_Recent_Chane = x.Field<String>("Most_Recent_Change_DT") //Unit_ID, Using_Dept, Status, Using_Dept_Desc, }; foreach (var row in fulljoin) { Table.Rows.Add(row); } 。但是本地引用是一种稀缺资源:如果你的JNI函数使用了很多它们,你应该尽快释放它们。

答案 2 :(得分:0)

添加@EJP所说的内容:只有在没有(强)引用它的情况下,对象才有资格进行垃圾回收。当您执行NewGlobalRef时,您将创建对对象的第二个引用,将引用数增加到2.本地引用仍将存在。

当您的函数退出时,它将被运行时删除,但假设您的函数很长。如果您调用DeleteGlobalRef,则会删除全局引用,但本地引用仍将不受影响。引用数量:1。只有在删除此引用之后,垃圾收集器才能声明该对象。