Android NDK: Why does this malloc () have no observable effect?

Here's a simplified version of the code I'm using

Java:

private native void malloc(int bytes); private native void free(); // this is called when I want to create a very large buffer in native memory malloc(32 * 1024 * 1024); // EDIT: after allocating, we need to initialize it before Android sees it as anythign other than a "reservation" memset(blob, '\0', sizeof(char) * bytes); ... // and when I'm done, I call this free() 

WITH

 static char* blob = NULL; void Java_com_example_MyClass_malloc(JNIEnv * env, jobject this, jint bytes) { blob = (char*) malloc(sizeof(char) * bytes); if (NULL == blob) { __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "Failed to allocate memory\n"); } else { char m[50]; sprintf(m, "Allocated %d bytes", sizeof(char) * bytes); __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, m); } } void Java_com_example_MyClass_free(JNIEnv * env, jobject this) { free(blob); blob = NULL; } 

Now when I call malloc () from MyClass.java, I expect to see 32M of allocated memory and that I can observe this drop in available memory somewhere. I did not see any indication of this, however, in adb shell dumpsys meminfo or adb shell cat /proc/meminfo . I am new to C but have tons of Java experience. I want to allocate a bunch of memory outside the Dalvik heap (so it is not controlled by Android / dalvik) for testing purposes. Hackbod made me believe that Android currently does not set limits on the amount of memory allocated in the Native code, so this is apparently the right approach. Am I doing it right?

+4
source share
2 answers

After memset() you will see an increase in the "personal / dirty" pages. If your device has additional command line utilities for developers, you can run procrank or showmap <pid> to see this easily. A root device is required.

If this fails, start the process of copying the contents of /proc/self/maps to the file before and after the selection. (The easiest way is to write it to external storage, you will need the WRITE_EXTERNAL_STORAGE permission in your manifest.) When comparing the map output, you should either see a new 32 MB region or an existing region expanding by 32 MB. This works because 32 MB is above the threshold of the dlmalloc internal heap, so memory should be allocated using the mmap () call.

There is no fixed limit on the amount of memory that you can allocate from your own code. However, the more you allocate, the tastier you look at the killer of a process with low kernel memory.

+3
source

You must return the allocated memory block in Java. Here are my test codes:

 JNIEXPORT jbyteArray Java_com_example_hyx_myapplication_MainActivity_mallocFromJNI(JNIEnv *env) { int length = 200*1024*1024; char *blob=(char *)malloc(length); memset(blob, 3, length); jbyteArray ret = (*env)->NewByteArray(env, length); (*env)->SetByteArrayRegion (env, ret, 0, length, blob); return ret; 

}

And after executing mallocFromJNI, meminfo shows that the native heap has increased accordingly: enter image description here

0
source

All Articles