JNI中GetStringChars函数中的isCopy

一直不明白这个isCopy是什么意思,只知道每次使用的时候都传NULL,今天看到了相关的资料,特来分享下。

 

  当从JNI函数GetStringChars中返回得到字符串B时,如果B是原始字符串java.lang.String的拷贝,则isCopy被赋值为JNI_TRUE。如果B和原始字符串指向的是JVM中的同一份数据,则isCopy被赋值为JNI_FALSE。当isCopy值为JNI_FALSE时,本地代码决不能修改字符串的内容,否则JVM中的原始字符串也会被修改,这会打破JAVA语言中字符串不可变的规则

  通常,因为你不必关心JVM是否会返回原始字符串的拷贝,你只需要为isCopy传递NULL作为参数。
  JVM是否会通过拷贝原始Unicode字符串来生成UTF-8字符串是不可以预测的,程序员最好假设它会进行拷贝,而这个操作是花费时间和内存的。一个典型的JVM会在heap上为对象分配内存。一旦一个JAVA字符串对象的指针被传递给本地代码,GC就不会再碰这个字符串。换言之,这种情况下,JVM必须pin这个对象。可是,大量地pin一个对象是会产生内存碎片的,因为,虚拟机会随意性地来选择是复制还是直接传递指针。
当你不再使用一个从GetStringChars得到的字符串时,不管JVM内部是采用复制还是直接传递指针的方式,都不要忘记调用ReleaseStringChars。根据方法GetStringChars是复制还是直接返回指针,ReleaseStringChars会释放复制对象时所占的内存,或者unpin这个对象。

这里有必要提一下另一个JNI函数:

const jchar* (JNIEnv *)->GetStringCritical(jstring _jstr, jboolean* copied);
    参数:
      _jstr 是字符串对象,
      copied 上面的方法已经做了解释了,这里就不多说了

  这个方法的作用是为了增加直接传回指向Java字符串的指针的可能性(而不是拷贝),JDK1.2出来了新的函数GetStringCritical/ReleaseStringCritical,

  需要注意的是:

  1). 在GetStringCritical/ReleaseStringCritical之间是一个关键区,在这个关键区域之间不能呼叫JNI的其他函数和会造成当前线程中断,或是会让当前线程等待的任何本地代码,否则将造成关键区代码执行期间垃圾回收器停止运作,任何触发垃圾回收器的线程也会暂停,其他的触发垃圾回收器的线程不能前进直到当前线程结束而激活垃圾回收器。

  2). 在关键区域中千万不要出现中断操作,或是在JVM中分配任何新对象,否则会造成JVM死锁
  3). 虽说这个函数会增加直接传回指向Java字符串的指针的可能性,不过还是会根据情况传回拷贝过的字符串 (ZC: 好蛋疼...)
  不支持GetStringUTFCritical,没有这样的函数,由于Java字符串用的是UTF-16,要转成UTF-8编码的字符串始终需要进行一次拷贝,所以没有这样的函数
这个方法和第四个方法(ZC: GetStringChars)是一样的功能

  其对应的释放内存指针的方法:
  (JNIEnv *)->ReleaseStringCritical(jstring _jstr, const jchar* _pjchar);

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值