2012-04-06 11 views
3

zu fangen Ich habe einen Block von Code, der in Android NDK riesige Mengen von Arbeitsspeicher zuweist. Last was ich brauche, ist die Verwendung von try - catch block für die Möglichkeit, es könnte NoMemoryError sein. Weißt du, wie man es im nativen SDK schreibt?Android NDK - Versuch, mit NoMemoryError

ich brauche gleiche Funktionalität wie dies umzusetzen:

 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; 
     } 
    } 
+0

Ihr Kommentar sagt 1MB, aber es wird tatsächlich 4MB jeder Iteration zuweisen. Das Problem mit diesem Code ist, dass Android abstürzt und brennt, bevor Sie eine Ausnahme bekommen. Das System wird versuchen, andere Apps und Dienste herunterzufahren, um den Speicher freizugeben, und dabei wird Android sehr langsam und beginnt sich schlecht zu benehmen. Anstatt das System so zu belasten, warum fragen Sie nicht einfach die Menge an freiem Speicher ab? – BitBank

+0

Ich brauche es nur zum Üben von NDK ... und ich denke, es gibt keine Möglichkeit, diese Funktion in NDK zu reproduzieren, was denkst du? Übrigens ist es nicht wichtig, ob es 1 MB oder 4 MB ist, ich überprüfe freien Speicher von der Laufzeit – Waypoint

Antwort

4

In Ihrer JNI-Funktion können Sie eine Java-Ausnahme mit dem Follow-Schnipsel werfen. Stellen Sie beim Kompilieren des systemeigenen Codes sicher, dass RTTI und Ausnahmen aktiviert sind.

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 können Sie einfach den OutOfMemoryError abfangen.

try { 
    // Make JNI call 
} catch (OutOfMemoryError e) { 
    //handle error 
} 
1

Android ist not very friendly to C++ exceptions (Sie mit einer speziellen Version der C++ Bibliothek von Android zur Verfügung gestellt verknüpfen müssen Ausnahmen haben). Vielleicht sollten Sie malloc() verwenden und seinen Rückgabewert überprüfen, um festzustellen, ob die Speicherzuweisung in Ordnung war?

1

Wenn Sie eine Ausnahme/Fehler in Ihrem systemeigenen Code auslösen, sollten Sie catchit. Ich würde jedoch annehmen, dass die Zuweisung eines großen Stücks nicht verwalteten Arbeitsspeichers mit Hilfe von malloc oder ähnlichem keinen Fehler auslöst, sondern Sie auf die harte Tour umbringt. Wenn Sie stattdessen das gleiche große Java-Array wie in Ihrem Java-Code erstellen, schlägt die Java-Methode, die Sie zum Erstellen des Arrays aufrufen, fehl und erstellt eine Ausnahme. Als Ausnahmebehandlung in JNI sehr unterschiedlich ist, müssen Sie für Ausnahmen in Ihrem nativen Code überprüfen etwas wie manuell mit:

exc = (*env)->ExceptionOccurred(env); 
if (exc) ...