Android NDK 内存使用

标签 android c memory-leaks android-ndk java-native-interface

我应该将我从相机接收到的每个 yuv 图像缓冲区逆时针旋转 90 度。我找到了这个 post在哪里使用java。此代码工作正常。 但我尝试过使用本地方法,因为我想使用具有相同逻辑但运行速度更快的方法。

JNIEXPORT jbyteArray JNICALL Java_com_ndk_example_utils_NativeUtils_rotateFrameBackward
      (JNIEnv *env, jobject obj, jbyteArray arr, jint w, jint h){

      jint arrSize = w*h*3/2;
      jbyte *data,*yuv;

      data = (*env)->GetByteArrayElements(env, arr, JNI_FALSE);

      yuv = (*env)->GetByteArrayElements(env, arr, JNI_FALSE);

      int x,y,i = 0;
      for(x = 0; x < w; x++){
        for(y = h-1;y >= 0;y--){
          yuv[i] = data[y*w+x];
          i++;
        }
      }

      i = arrSize - 1;
      for(x = w-1;x > 0;x=x-2)
      {
        for(y = 0;y < h/2;y++)
        {
          yuv[i] = data[(w*h)+(y*w)+x];
          i--;
          yuv[i] = data[(w*h)+(y*w)+(x-1)];
          i--;
        }
      }
      (*env)->ReleaseByteArrayElements(env, arr, yuv, JNI_ABORT);
      yuv = 0;
      data = 0;
      return arr;
    }

当我在我的 htc 816(v5.1) 上启动这个方法时它工作正常,但是当我在三星 S3(v4.3) 和联想 P-70(v4.4.2) 上启动这个应用程序时,应用程序崩溃了.在 Android Studio 的 Android 监视器选项卡中,我看到了 内存使用量一直在增加,直到我的应用程序崩溃。在我的 htc 中,我没有遇到任何问题。有什么想法吗?

最佳答案

您使用datayuvarr 执行双重GetByteArrayElements,然后只释放yuv 。您也不检查是否使用最后一个参数制作了副本,您只需输入 JNI_FALSE。你不应该那样做,你应该使用一个 bool 参数来接收值,而不是试图告诉系统是否复制。

因此,您应该在最后释放两个指针。

此外,如果此代码有效,则意味着实际上已创建副本,因为您正在从同一内存区域读取和写入,这会导致图像损坏。

关于Android NDK 内存使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35746149/

相关文章:

android - Activity 泄漏了窗口/对话框(又是这个!)

c - 创建共享对象时不能使用针对 .data 的重定位 R_X86_64_32S(64 位 NASM + gcc)

将元素添加到固定长度数组并删除第一个元素的干净方法?

malloc 中的 C 结构数组

android - picasso 清晰的内存

Android 泄漏金丝雀日志

java - Android Webview 不适用于 Android 4.4

android - 使用 TalkBack 或 VoiceOver 时样式居中的复选框不可选中

android - 如何在 YouTube api v3 中获取 YouTube 视频的 cc 字幕

android - 如何在android中的LinearLayout中居中ListView