Trần Kim Dự
Trần Kim Dự

Reputation: 6102

Android Native: cannot allocate large memory under native layer

As I know, Android limits java heap size for one process. But if we allocate under native layer, we can allocate as many as we want (unless it's larger than available memory).

So, I'm writing a test for this.

Firstly I create max memory I can allocate:

 ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
 int realAllowMemory = am.getMemoryClass();

Secondly I allocate a native memory with this size:

JNIEXPORT jbyteArray JNICALL
Java_memory_hqt_com_heapsizetesting_jnitest_JNIActivity_getBigDataFromJni(JNIEnv *env, jobject instance, jint memory) {
     jbyteArray ret = (*env)->NewByteArray(env, memory);
     return ret;
}

And I will call this method by:

    public native byte[] getBigDataFromJni(int memory);


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getBigDataFromJni(realAllowMemory * 1000 * 1000);
    }

But when I do this, I will meet exception:

JNI DETECTED ERROR IN APPLICATION: JNI NewByteArray called with pending exception 'java.lang.OutOfMemoryError' thrown in byte[] memory.hqt.com.heapsizetesting.jnitest.JNIActivity.getBigDataFromJni(int):-2

Although as I test, realAllowMemory is about 256MB, but available memory is about 1000 MB. Please explain for me at this point.

Upvotes: 1

Views: 766

Answers (1)

Anton Malyshev
Anton Malyshev

Reputation: 8861

You are calling Java allocation method in your native part. It has the same restrictions as for java code. To avoid it use native allocation functions, such as malloc().

Upvotes: 4

Related Questions