2012-01-06 4 views
2

Mon application fonctionnait bien il y a environ 5 jours! Aujourd'hui, j'essaie de le faire fonctionner, et ça devient complètement fou!OutOfMemoryError Android

Je reçois ce message dans logcat avant qu'il jette enfin le OutOfMemoryError

01-06 04:14:17.088: D/dalvikvm(454): GC_FOR_MALLOC freed 5702 objects/326856 bytes in 76ms 
01-06 04:14:17.228: D/dalvikvm(454): GC_FOR_MALLOC freed 680 objects/157944 bytes in 57ms 
01-06 04:14:17.228: I/dalvikvm-heap(454): Grow heap (frag case) to 2.860MB for 121834-byte allocation 
01-06 04:14:17.288: D/dalvikvm(454): GC_FOR_MALLOC freed 1 objects/81232 bytes in 60ms 
01-06 04:14:17.378: D/dalvikvm(454): GC_FOR_MALLOC freed 5 objects/192 bytes in 65ms 
01-06 04:14:17.388: I/dalvikvm-heap(454): Grow heap (frag case) to 2.957MB for 182746-byte allocation 
....and so on... 

puis enfin cette erreur apparaît:

01-06 04:24:49.218: E/AndroidRuntime(511): java.lang.OutOfMemoryError 
01-06 04:24:49.218: E/AndroidRuntime(511): at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:97) 
01-06 04:24:49.218: E/AndroidRuntime(511): at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:136) 
01-06 04:24:49.218: E/AndroidRuntime(511): at java.lang.StringBuilder.append(StringBuilder.java:272) 
01-06 04:24:49.218: E/AndroidRuntime(511): at java.io.BufferedReader.readLine(BufferedReader.java:452) 
01-06 04:24:49.218: E/AndroidRuntime(511): at appsbidder.clientstuff.Utils.openURL(Utils.java:285) 
01-06 04:24:49.218: E/AndroidRuntime(511): at appsbidder.clientstuff.Utils.getFeatured(Utils.java:224) 
01-06 04:24:49.218: E/AndroidRuntime(511): at appsbidder.FeaturedAppsActivity$GridViewAdapter.<init>(FeaturedAppsActivity.java:45) 
01-06 04:24:49.218: E/AndroidRuntime(511): at appsbidder.FeaturedAppsActivity.onCreate(FeaturedAppsActivity.java:28) 
01-06 04:24:49.218: E/AndroidRuntime(511): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
01-06 04:24:49.218: E/AndroidRuntime(511): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
01-06 04:24:49.218: E/AndroidRuntime(511): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
01-06 04:24:49.218: E/AndroidRuntime(511): at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
01-06 04:24:49.218: E/AndroidRuntime(511): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
01-06 04:24:49.218: E/AndroidRuntime(511): at android.os.Handler.dispatchMessage(Handler.java:99) 
01-06 04:24:49.218: E/AndroidRuntime(511): at android.os.Looper.loop(Looper.java:123) 
01-06 04:24:49.218: E/AndroidRuntime(511): at android.app.ActivityThread.main(ActivityThread.java:4627) 
01-06 04:24:49.218: E/AndroidRuntime(511): at java.lang.reflect.Method.invokeNative(Native Method) 
01-06 04:24:49.218: E/AndroidRuntime(511): at java.lang.reflect.Method.invoke(Method.java:521) 
01-06 04:24:49.218: E/AndroidRuntime(511): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
01-06 04:24:49.218: E/AndroidRuntime(511): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
01-06 04:24:49.218: E/AndroidRuntime(511): at dalvik.system.NativeStart.main(Native Method) 

Je CROIS rétréci vers le bas à ce bloc de code, mais je ne sais pas pourquoi ça ne marche pas! Cela fonctionnait toujours bien avant. Le seul problème que je peux penser est que maintenant il doit aller chercher plus de données qu'avant, donc quelque part un débordement se produit, mais où?

public JSONArray openURL(String urlParams, String url) 
    { 


    HttpsURLConnection connection = null; 
    try { 
     System.setProperty("http.keepAlive", "false"); 
     //Create connection 
     connection = (HttpsURLConnection)new URL(url).openConnection(); 
     connection.setRequestMethod("POST"); 


     connection.setRequestProperty("Content-Type", 
     "application/x-www-form-urlencoded"); 

     connection.setRequestProperty("Content-Length", "" + 
      Integer.toString(urlParams.getBytes().length)); 
     connection.setRequestProperty("Content-Language", "en-US"); 


     connection.setUseCaches(false); 
     connection.setDoInput(true); 
     connection.setDoOutput(true); 

     //Send request 
     DataOutputStream wr = new DataOutputStream (
        connection.getOutputStream()); 
     wr.writeBytes (urlParams); 
     wr.flush(); 
     wr.close(); 

     //Get Response  
     InputStream is = connection.getInputStream(); 
     BufferedReader rd = new BufferedReader(new InputStreamReader(is)); 
     String line; 
     JSONArray ja = new JSONArray(); 
     while((line = rd.readLine()) != null) { 
      ja = new JSONArray(line); 
     } 
     rd.close(); 
     return ja; 

    } catch (Exception e) { 

     e.printStackTrace(); 
     return null; 

    } finally { 

     if(connection != null) { 
     connection.disconnect(); 
     } 

    } 

    } 

Répondre

2

probablement ici:

while((line = rd.readLine()) != null) { 

Si la réponse contient grande JSON en une seule ligne, alors vous pouvez avoir un OutOfMemoryError sur cette ligne. Vous pouvez vérifier cela en vérifiant quelle réponse arrive manuellement.

+1

comment pourrais-je le fixer, si le JSON est très grand? – volk

0

Je pense que cette ligne de code est erroné:

JSONArray ja = new JSONArray(); 
     while((line = rd.readLine()) != null) { 
      ja = new JSONArray(line); // in every step of loop, you create an object, that is wrong for memory 
     } 

utiliser:

JSONArray ja = new JSONArray(); 
     while((line = rd.readLine()) != null) { 
      ja.add(line); 
     } 

Hope this helps.

+0

Je l'ai essayé, toujours le même problème. Pensez-vous qu'il peut être le JSON est juste trop grand? – volk

+0

Je ne pense pas, mais après une petite recherche, j'ai trouvé un fil à ce sujet, vérifiez cela: http://stackoverflow.com/questions/2886599/android-outofmemoryerror-loading-json-file – barisatbas

3

Ce que je peux voir que vous devriez regarder ceci:

 while((line = rd.readLine()) != null) { 
      ja = new JSONArray(line); 
     } 

Puisque l'erreur est trown à l'appel de méthode readLine.

01-06 04:24:49.218: E/AndroidRuntime(511): at java.lang.StringBuilder.append(StringBuilder.java:272) 
01-06 04:24:49.218: E/A ndroidRuntime(511): at java.io.BufferedReader.readLine(BufferedReader.java:452) 

Vous devriez essayer ceci:

char[] buffer = new char[8064]; 
BufferedReader rd = new BufferedReader(new InputStreamReader(is), buffer.length); 

et l'utilisation lire au lieu de readLine

rd.read(buffer, 0, buffer.length) 

Il y a beaucoup d'exemples à ce sujet.

EDIT:

de mon ancien projet:

readResponse(InputStream inputStream) { 

ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
byte[] buffer = new byte[8064]; 

while(true) { 
int rd = inputStream.read(buffer) 
if(rd == -1)break; 
stream.write(buffer, 0 , rd); 
} 

stream.flush(); 
buffer = stream.toByteArray(); 
String response = new String(buffer); 
inputStream.close(); 

return response; 
} 
+0

cela ne veut pas fonctionne nécessairement car le premier argument de la méthode read nécessite un char [] plutôt que le byte []. – volk

+0

S'il vous plaît regarder le code après ma modification. –

+0

ouais, je l'ai juste regardé. Désolé le problème REAL est que je ne peux pas utiliser de cette façon parce que ma variable "line" est une chaîne. seul le readLine est applicable ici, sauf si je manque quelque chose – volk

Questions connexes