简体   繁体   中英

Android passing large float arrays from native to java via jni. Getting error if over certain size

I am wanting to pass a single large array of floats anywhere up too and beyond float[100000]. I have a setup successfully passing an array of size 212. But any larger and it crashes giving the following error message in the logcat:

"Fatal signal 11 (SIGSEGV) at 0xbe949000 (code=1)"

My code

Native function

NIEXPORT jfloatArray JNICALL  Java_carron_graphics_benchmark_NativeWrapper_getArrayNative(JNIEnv * env, jclass cls) {

    int tempSize = mParticleSystem->mSizeOfSystem*2;

    jfloat cArray[tempSize];
    jsize len = sizeof(cArray);

    jfloatArray jArray = (*env).NewFloatArray(len);

    if (jArray != NULL) {

        jint i;

        for (i = 0; i < tempSize; i++) {
            cArray[i] = mParticleSystem->mParticlePositions[i];
        }
        (*env).SetFloatArrayRegion(jArray, 0, len, cArray);
    }
    return jArray;
}

Java Pretty straight forward simply grabbing the array. If I create and pass a float array larger than 212 though I get the error as shown above.

float tempArray[] = NativeWrapper.getArrayNative();

Has anyone encountered this problem or can see how I can get around this limit? Also I apologise if this question has been answered already, I could not find this specific issue nor an answer. Any help will be appreciated :)

EDIT:

For updating a global jfloatArray to avoid the garbage collector when frequently fetching an array through jni.

static jfloatArray gArray = NULL;

JNIEXPORT jfloatArray JNICALL Java_carron_graphics_benchmark_NativeWrapper_getArrayNative(JNIEnv * env, jclass cls)  {
    int arrayLength = mParticleSystem->mSizeOfSystem*2;

    if (gArray == NULL)
    {
        // create array
        jfloatArray jArray;
        jArray = env->NewFloatArray(arrayLength);
        gArray = (jfloatArray)env->NewGlobalRef(jArray);
    }

    // Update global 
    env->SetFloatArrayRegion(gArray, 0, arrayLength, mParticleSystem->mParticlePositions);

    return gArray;
}

Problem with your code is that stack is limited in size. You can not put there large arrays ( jfloat cArray[tempSize] variable). If you want to create large array, do that on heap, like Alex is showing you.

If mParticleSystem->mParticlePositions is float array then this code will be better:

int tempSize = mParticleSystem->mSizeOfSystem*2;
jfloatArray jArray = env->NewFloatArray(tempSize);

if (jArray != NULL)
{
    env->SetFloatArrayRegion(jArray, 0, tempSize, mParticleSystem->mParticlePositions);
}
return jArray;

If it is not float array then use following code, no need to create additional float array:

int tempSize = mParticleSystem->mSizeOfSystem*2;
jfloatArray jArray = env->NewFloatArray(tempSize);

if (jArray != NULL)
{
    if (float* ptr = env->GetFloatArrayElements(jArray, NULL))
    {
        for (int i=0; i<tempSize; i++)
        {
            ptr[i] = mParticleSystem->mParticlePositions[i];
        }
        env->ReleaseFloatArrayElements(jArray, ptr, JNI_COMMIT);
    }
}

return jArray;

EDIT

To store jArray somewhere else (for example globally) do following:

static jfloatArray gArray = NULL;

jfloatArray fun(...)
{
    jfloatArray jArray;

    if (gArray == NULL)
    {
        // create array
        jArray = env->NewFloatArray(tempSize);
        gArray = (jfloatArray)env->NewGlobalRef(jArray);
    }
    else
    {
        jArray = gArray;
    }

    // ... here fill/modify jArray
    // SetFLoatArrayRegion/GetFloatArrayElemeents/ReleaseFloatArrayElements

    return jArray;
}

When done free the memory:

void freeArray(...)
{
    env->DeleteGlobalRef(gArray);
    gArray = NULL;
}

Your code does not compile: you probably had

jfloat *cArray = new jfloat[tempSize];

in your compiled code.

The mistake in your code is in call to NewFloatArray(). You should call NewFloatArray(tempSize), not (sizeof(cArray)).

Also note that there is no need to work with intermediate copy of mParticleSystem->mParticlePositions. If it is an array of float, you can simply use it for SetFloatArrayRegion().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM