Jni Byte數組傳遞異常

異常

背景 : 爲了做個YUV格式的轉換

報錯提醒: JNI : pin count on array [對象地址] ([B) is now [數字]

當達到一定的程度,程序就Crash掉了

報錯如下

11-04 10:55:16.631: E/dalvikvm(3833): Failed adding to JNI pinned array ref table (1024 entries)
11-04 10:55:16.631: I/dalvikvm(3833): "main" prio=5 tid=1 RUNNABLE
11-04 10:55:16.631: I/dalvikvm(3833):   | group="main" sCount=0 dsCount=0 obj=0x419e7cd8 self=0x419d63c8
11-04 10:55:16.631: I/dalvikvm(3833):   | sysTid=3833 nice=0 sched=0/0 cgrp=apps handle=1074176340
11-04 10:55:16.631: I/dalvikvm(3833):   | state=R schedstat=( 1828552233 638214124 2555 ) utm=168 stm=14 core=2
11-04 10:55:16.631: I/dalvikvm(3833):   at com.xinwei.sdc.media.rotate.NewRotate.transNV21ToNV12b(Native Method)
11-04 10:55:16.631: I/dalvikvm(3833):   at com.example.niojni.MainActivity.test(MainActivity.java:78)
11-04 10:55:16.631: I/dalvikvm(3833):   at com.example.niojni.MainActivity.access$1(MainActivity.java:60)
11-04 10:55:16.631: I/dalvikvm(3833):   at com.example.niojni.MainActivity$2.onClick(MainActivity.java:50)
11-04 10:55:16.631: I/dalvikvm(3833):   at android.view.View.performClick(View.java:4438)
11-04 10:55:16.631: I/dalvikvm(3833):   at android.view.View$PerformClick.run(View.java:18427)
11-04 10:55:16.631: I/dalvikvm(3833):   at android.os.Handler.handleCallback(Handler.java:733)
11-04 10:55:16.631: I/dalvikvm(3833):   at android.os.Handler.dispatchMessage(Handler.java:95)
11-04 10:55:16.631: I/dalvikvm(3833):   at android.os.Looper.loop(Looper.java:136)
11-04 10:55:16.631: I/dalvikvm(3833):   at android.app.ActivityThread.main(ActivityThread.java:5120)
11-04 10:55:16.631: I/dalvikvm(3833):   at java.lang.reflect.Method.invokeNative(Native Method)
11-04 10:55:16.631: I/dalvikvm(3833):   at java.lang.reflect.Method.invoke(Method.java:515)
11-04 10:55:16.631: I/dalvikvm(3833):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788)
11-04 10:55:16.631: I/dalvikvm(3833):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:604)
11-04 10:55:16.631: I/dalvikvm(3833):   at dalvik.system.NativeStart.main(Native Method)
11-04 10:55:16.631: E/dalvikvm(3833): VM aborting
11-04 10:55:16.631: A/libc(3833): Fatal signal 6 (SIGABRT) at 0x00000ef9 (code=-6), thread 3833 (.example.niojni)

檢查問題代碼

JNIEXPORT jint JNICALL Java_com_xinwei_sdc_media_rotate_NewRotate_transNV21ToNV12b
  (JNIEnv * env, jobject thiz, jbyteArray dst, jbooleanArray src)
{
    clock_t start_t, end_t, total_t;
    start_t = clock();
    jbyte * srcp = (*env)->GetByteArrayElements(env, src, 0);
    jbyte * dstp = (*env)->GetByteArrayElements(env, dst, 0);
    //這個函數做了個複製memcpy,以及調換某些位置而已
    transNV21ToNV12(_width, _height, dstp, srcp);
    end_t = clock();
    total_t = end_t - start_t;
    LOGD("B transNV21ToNV12b() cost time : %ld", total_t);
}

修復Bug後的代碼

JNIEXPORT jint JNICALL Java_com_xinwei_sdc_media_rotate_NewRotate_transNV21ToNV12b
  (JNIEnv * env, jobject thiz, jbyteArray dst, jbooleanArray src)
{
    clock_t start_t, end_t, total_t;
    start_t = clock();
    jbyte * srcp = (*env)->GetByteArrayElements(env, src, 0);
    jbyte * dstp = (*env)->GetByteArrayElements(env, dst, 0);
    transNV21ToNV12(_width, _height, dstp, srcp);
    (*env)->ReleaseByteArrayElements(env, src, srcp, JNI_ABORT);
    (*env)->ReleaseByteArrayElements(env, dst, dstp, 0);
    end_t = clock();
    total_t = end_t - start_t;
    LOGD("B transNV21ToNV12b() cost time : %ld", total_t);
}

謹記

釋放很重要
ReleaseByteArrayElements((JNIEnv *)env, (jbyteArray )src, (jbyte *)srcp, jnimode);

額外

jnimode有3個常用值,其中一個是0,另外兩個如下:

#define JNI_COMMIT      1           /* copy content, do not free buffer */
#define JNI_ABORT       2           /* free buffer w/o copying back */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章