3

I have block of code, which in Android NDK allocates huge ammounts of memory. Last what I need is to use try - catch block for possibility, there might be NoMemoryError. Do you know how to write it in native SDK?

I need to implement same functionality as this:

        for(int i=1;i<50;i++){
        try{
            int[] mega =new int[i*1024*1024];//1MB

        }catch (OutOfMemoryError e) {
            usedMemory= (Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory())/new Float(1048576.0);
            usedText=usedMemory+" MB";
            tw.setText(usedText);          
            break;
        }
    }
Waypoint
  • 17,283
  • 39
  • 116
  • 170
  • Your comment says 1MB, but it will actually allocate 4MB each iteration. The problem with that code is that Android will crash and burn before you get an exception. The system will try to shut down other apps and services to free up the memory and in the process Android will get very slow and eventually start misbehaving. Instead of stressing the system like that, why don't you just query the amount of free memory? – BitBank Apr 06 '12 at 20:42
  • I just need it for practising NDK... and I think there is no way how to reproduce this function in NDK, what do you think? btw, it is not important, whether it is 1 MB or 4 MB, I check free memory from runtime – Waypoint Apr 07 '12 at 15:08

3 Answers3

4

In your JNI function you can throw a java exception using the follow snippet. When compiling the native code make sure RTTI and exceptions are enabled.

try {
  int *mega = new int[1024 * 1024];
} catch (std:: bad_alloc &e) {
  jclass clazz = jenv->FindClass("java/lang/OutOfMemoryError");
  jenv->ThrowNew(clazz, e.what());
}

In Java you can simply catch the OutOfMemoryError.

try {
  // Make JNI call
} catch (OutOfMemoryError e) {
  //handle error
}
Frohnzie
  • 3,559
  • 1
  • 21
  • 24
1

Android is not very friendly to C++ exceptions (you must link with a special version of the C++ library provided by Android to have exceptions). Maybe you should use malloc() and check its return value to see if memory allocation was OK?

Community
  • 1
  • 1
gfour
  • 959
  • 6
  • 9
1

If you trigger an exception/error in your native code you should be able to catch it. However, I would assume that allocating a big chunk of unmanaged memory using malloc or similar will not trigger an error but kill you app the hard way. If you create the same big java array as in your java code instead, however, the java method you call to create the array will fail and create an exception. As exception handling in JNI is very different you have to check for exceptions in your native code manually using something like:

exc = (*env)->ExceptionOccurred(env);
if (exc) ...
Niels
  • 313
  • 2
  • 9