关于JNI的本地引用

      使用DeleteLocalRef删除了JNI的本地引用后,相应的referencereference table中被删除,所引用的java对象所占的内存空间将被释放。或者当本地方法执行完毕,返回java层的时候,为这个本地方法所创建的reference table中所有的Local Reference被删除掉,java对象所占内存被回收。

      但是内存释放了,你还可以使用这个引用一段时间。例如这个本地引用是jstring类型,它被删除后,仍可以使GetStringUTFChar来使用这个本地引用,但是指不定什么时候就不能用了,等着java虚拟机崩溃吧。且:

jstring jstr = env->NewStringUTF("test");
env->DeleteLocalRef(jstr);
if(JNI_TRUE == env->IsSameObject(jstr, NULL))
{
    //分支1
    //局部引用的对象已经被回收
]
else
{
    //分支2
    //局部引用的对象没有被被回收
}

      不能用上面这种方法来判断本地引用是否是有效的。与java虚拟机有关,我试验的有一个环境是可以执行,但会走到分支2。有一个删除本地引用后再用IsSameObject函数,虚拟机会崩溃:the reference is invalid,别的环境不知道,不过这方法不靠谱。

     总结一下:

  1. 新创建一个局部引用,当你不再使用它的时候,最好立刻使用DeleteLocalRef干掉它,否则在一个本地方法中创建过多的本地引用有可能会出两个错误,一个是:Local Reference table overflow,因为一个本地方法默认所能创建的本地引用个数是有限制的,比如512;还有一个是:out of memory,这是本地引用所关联到的java对象泄漏所导致的错误(java heap 也不是无限大)。删掉了,就可以及时释放相应的资源,增强可移植性。
  2. 不要试图用static变量去保存本地引用,虽然有些情况你还能用,但那是非常危险的。
  3. 调用DeleteLocalRef之后,内存就会被释放,不会造成内存泄露。
  4. IsSameObject这个函数用来判断局部引用是否有效不太靠谱。

         不足之处望指正。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值