众所周知,在C / C ++拥有的线程中创建Java对象,我们有责任根据需要调用Running Sum: Over All
或DeleteLocalRef
。
我有一些像
这样的代码Push/Pop LocalFrame
本机代码创建一个字节数组,它在多个线程/调用中重复使用,一旦我们完成它,我在缓冲区上调用jbyteArray buffer = env->NewByteArray((jsize)requiredSize);
longTermBufferReference = (jbyteArray)env->NewGlobalRef(buffer);
。
问题是,当我完成时,我必须在DeleteGlobalRef
上调用DeleteLocalRef,或者GlobalRef是否完全拥有该对象?
答案 0 :(得分:3)
在垃圾收集系统中,没有对象所有权这样的东西。有根对象引用和对象引用可以直接或间接从根进行访问。 (不考虑弱引用)。
JNI本地引用和JNI全局引用都是根引用。创建其他引用不会影响现有引用,也不会从根引用列表中删除它们。
所以,是的,必须删除本地引用(就像必须删除全局引用一样)。您已经知道可以使用DeleteLocalRef
或PopLocalFrame
显式执行此操作,或者,当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。只有在删除此引用之后,垃圾收集器才能声明该对象。