Android native malloc() allows allocations beyond RAM but process is killed during memset; no onLowMemory() / onTrimMemory() callbacks

2 weeks ago 21
ARTICLE AD BOX

I am working on an Android application that uses native C/C++ code and performs large memory allocations using malloc().

On an 8 GB Android device (Android 14+), I repeatedly allocate large chunks of memory (approximately 1 GB per allocation) using malloc().

What I observe is:

malloc() returns a non-null pointer for each allocation

If I do not initialize or access the allocated memory, the application continues to run

In this case, the total allocated size can exceed the physical RAM size of the device

When I initialize the memory using memset(), the application is killed after a few iterations

The failure happens during memset(), not at the malloc() call

There is:

No malloc() failure

No NULL return

The process is terminated abruptly

After termination, logcat shows messages such as:

InputDispatcher: channel 'com.example.app/.MainActivity' ~ Channel is unrecoverably broken and will be disposed

Additional details:

The pointer returned by malloc() appears valid until memset() is executed

The number of successful allocations varies, but failure consistently occurs after a few large allocations when memory is accessed

The app defines an Application subclass -- Neither onLowMemory() nor onTrimMemory() is invoked before the process is killed

I am trying to understand:

Why malloc() allows allocating memory beyond physical RAM when it is not accessed?

Why the process is killed during memset() instead of malloc() returning nullptr?

#include <stdlib.h> #include <string.h> #include <android/log.h> #define ONE_GB (1024ULL * 1024 * 1024) void allocate_chunks(int iterations) { for (int i = 0; i < iterations; i++) { void* ptr = malloc(ONE_GB); __android_log_print(ANDROID_LOG_INFO, "NATIVE", "Iteration %d, ptr=%p", i, ptr); if (!ptr) { __android_log_print(ANDROID_LOG_ERROR, "NATIVE", "malloc returned NULL"); return; } // Uncommenting the following line causes the app to be killed memset(ptr, 0, ONE_GB); } }
Read Entire Article