NDK内存管理-引用
NDK中的内存管理:C/C++的new/malloc和delete/free以及JNI引用。
Java和C/C++内存管理的区别
三种引用的区别
在JNI规范中定义了三种引用:
- 局部引用(LocalReference)
- 全局引用(Global Reference)
- 若全局引用(Weak Global Reference)
因生命周期限制,不能在外部定义一个全局变量接受局部引用,在其他函数使用
之前多线程的代码中使用过,例如:
jobject appClassloader = env->NewGlobalRef(TestJclass); // 使用方式:用参数传递,或者定义一个全局变量接收也行 pthread_create(&thread, nullptr, threadtest, appClassloader); env->DeleteGlobalRef(appClassloader);
作用域和全局引用是相同的,但是如果内存紧张可能会被ART给释放掉
再JNI种局部引用的创建也是受局部引用表限制的
for (int i = 0; i < 2048; ++i) { jstring content = env->NewStringUTF("test localreference"); __android_log_print(4, "xiaoeryu->jni", "localreference number->%d", i); }
例如这样只创建不删除,有些引用会被自动释放掉
需要在每次循环结束加上
env->DeleteLocalRef(content);
测试了之后发现加上比之前好点但是也不稳定,有些变量还是会被自动释放掉,所以还是尽量不要这样使用。
EnsureLocalCapacity
- 创建多引用之前可以用EnsureLocalCapacity()测试一下能否创建成功
int len = 10; if (env->EnsureLocalCapacity(len) == 0){ for (int i = 0; i < len; ++i) { jstring content = env->NewStringUTF("test EnsureLocalCapacity"); __android_log_print(4, "xiaoeryu->jni", "EnsureLocalCapacity number->%d", i); } }
PushLocalFrame/PopLocalFrame
- 局部引用堆栈的创建和销毁
jobject testPushAndPopLocalFrame(JNIEnv* env){ jobject result = nullptr; if (env->PushLocalFrame(20) == 0){ for (int i = 0; i < 18; ++i) { jstring tmp = env->NewStringUTF("xiaoeryu"); } jstring tmp_1 = env->NewStringUTF("result_1"); jstring tmp_2 = env->NewStringUTF("result_2"); result = env->PopLocalFrame(tmp_1); // 保留tmp_1 } return result; }
- 标题: NDK内存管理-引用
- 作者: xiaoeryu
- 创建于 : 2023-10-17 23:52:33
- 更新于 : 2023-10-19 11:10:39
- 链接: https://github.com/xiaoeryu/2023/10/17/NDK内存管理-引用/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论