NDK-JNI的一些实践推荐

  • 内容
  • 评论
  • 相关

回收本地引用

我们在使用jni的时候,除了要遵循原生的内存管理规范,比如new出来的对象需要delete掉,还要额外对于jni的对象进行回收处理。

不需要回收的类型:jboolean、 jchar 、jint等基础数据类型

需要回收的类型:全局引用、jobject以及其子类jclass、jstring、jarray等

释放方法

1、jstring & char *

2、 jobject,jobjectArray,jclass ,jmethodID等引用类型

3、jbyteArray

4、GetByteArrayElements

5、NewGlobalRef

缓存MethodID以及FieldID

我们在调用java方法的时候都是通过jni去间接调用,每一次都需要FindClass、GetMethodID、GetFieldID,但是jni操作其实是很耗费性能的,所以我们可以直接将MethodID、FieldID给缓存起来,这样就可以提高效率。

1、在使用时缓存

C中的static变量可以只初始化一次,然后在程序运行期间一直存在,所以我们可以使用static局部变量来在使用时缓存

2、在类加载的时候缓存

可以看到,我们在java的static方法中主动进行调用去缓存ID

两种方式的区别

比起在类加载时进行缓存,使用时缓存有如下缺点

1、使用时缓存,每次都得判断是否为null

2、方法id和字段id在类被unload的时候就会失效,如果类被unload了再load,那么缓存的id就不对了

为什么不能缓存jclass

jclass是jobject的子类,当我们在native方法中使用FindClass或者GetObjectClass获取jclass的时候,获取到的只是一个局部引用,当方法结束以后,局部引用会被系统回收,当我们再次调用的时候,就会让程序崩溃。

更多关于局部引用的详解请参看:https://www.ibm.com/developerworks/cn/java/j-lo-jnileak/

参数传递最好使用基础类型

我们可以看到,sumValues2是传递的object,我们想获取其字段,需要使用jni操作,所以如果不是非必要,我们可以在java层就将字段拆解传递

https://blog.csdn.net/c1481118216/article/details/77727573

https://www.ibm.com/developerworks/cn/java/j-lo-jnileak/

https://www.kancloud.cn/owenoranba/jni/120442

评论

0条评论

发表评论

电子邮件地址不会被公开。