1

我有两个函数,我得到一个 ReferenceTable 溢出。消耗的数组条目的摘要是:

     1 of byte[] (3 elements)
   446 of byte[] (75 elements) (2 unique instances)
   576 of byte[] (147 elements) (2 unique instances)
     1 of int[] (25 elements)

我真的检查了代码,发现有错误,但没有发现。我得到它们后释放数组。唯一的问题是这些函数被调用了数千次,这可能是原因吗?

这是我所有的本机代码:

调用一次:

JNIEXPORT void JNICALL Java_ar_com_teasoft_Image_nativeUnlock(
            JNIEnv *env, jclass clazz, jobject bitmap) {
        AndroidBitmap_unlockPixels(env, bitmap);
    }

调用一次:

JNIEXPORT jlong JNICALL Java_ar_com_teasoft_Image_nativeLock(
        JNIEnv *env, jclass clazz, jobject bitmap) {
    int ret;
    AndroidBitmapInfo info;
    if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
        LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
        return 0;
    }
    if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
        LOGE("Bitmap format is not RGBA_8888!");
        return 0;
    }
    void* bitmapPixels;
    if ((ret = AndroidBitmap_lockPixels(env, bitmap, &bitmapPixels)) < 0) {
        LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
        return 0;
    }
    return (jlong) bitmapPixels;

}

多次调用:

JNIEXPORT void JNICALL Java_ar_com_teasoft_Image_nativeCopyPixels(
        JNIEnv *env, jclass clazz, jlong dataRef, jintArray sourceIndexes,
        jintArray targetIndexes, jint count) {
    argb* sourcePixels;
    argb* targetPixels;
    jint *sourceArray = env->GetIntArrayElements(sourceIndexes, NULL);
    jint *targetArray = env->GetIntArrayElements(targetIndexes, NULL);
    for (int i = 0; i < count; i++) {
        sourcePixels = (argb*)((char*) dataRef + sourceArray[i] * 4);
        targetPixels = (argb*)((char*) dataRef + targetArray[i] * 4);
        (*targetPixels) = (*sourcePixels);
    }
    env->ReleaseIntArrayElements(sourceIndexes, sourceArray, JNI_ABORT);
    env->ReleaseIntArrayElements(targetIndexes, targetArray, JNI_ABORT);

    }

多次调用:

JNIEXPORT void JNICALL  Java_ar_com_teasoft_Image_nativeGetRGB(
        JNIEnv *env, jclass clazz, jlong dataRef, jintArray indexes,
        jbyteArray destRgb) {
    jint *array = env->GetIntArrayElements(indexes, NULL);
    jbyte *dstarray = env->GetByteArrayElements(destRgb, NULL);
    int size = env->GetArrayLength(indexes);
    char* sourcePixels;
    int dstCount = 0;
    for (int i = 0; i < size; i++) {
        sourcePixels = (char*) dataRef + array[i] * 4;
        dstarray[dstCount++] = (*(sourcePixels + 1));
        dstarray[dstCount++] = (*(sourcePixels + 2));
        dstarray[dstCount++] = (*(sourcePixels + 3));
    }
    env->ReleaseIntArrayElements(indexes, array, JNI_ABORT);
    env->ReleaseByteArrayElements(destRgb, dstarray, JNI_COMMIT);
}

综上所述,好像没有释放的那个,是byte[]的,所以应该是函数nativeGetRGB中的那个。但我找不到错误在哪里。

请帮忙!问候, 胡安·伊格纳西奥

4

1 回答 1

2

Java_ar_com_teasoft_Image_nativeGetRGB():

据我所知,您需要通过传递而不是传递来提交释放任何临时数组副本to 。的第二个参数是一个指向布尔值的指针,如果返回的数组是一个副本,而不是固定内存,它将被设置为 true。0JNI_COMMITReleaseByteArrayElements()Get*ArrayElements()

Java_ar_com_teasoft_Image_nativeCopyPixels():

您可能还想在这里传递0而不是JNI_ABORT,它会丢弃所有内容:

env->ReleaseIntArrayElements(targetIndexes, targetArray, JNI_ABORT);

数组的棘手之处在于,释放模式仅适用于复制的数组,因为固定内存被直接修改。没有办法强制阵列复制或固定。

于 2013-09-21T23:53:33.683 回答