2012-01-06 4 views
2

약 5 일 전에 내 애플리케이션이 정상적으로 실행되고있었습니다! 오늘, 나는 그것을 실행하려고 노력하고, 그 절대적으로 열매가! 그것은 마침내 OutOfMemoryError를 던졌습니다 전에OutOfMemoryError Android

나는 로그 캣이 메시지를 받고 있어요

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... 

까지 다음 마지막으로이 오류가 온다 : 나는이 블록을 좁혀 THINK

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) 

코드,하지만 왜 작동하지 않는지 모르겠다! 전에는 항상 잘 작동했습니다. 내가 생각할 수있는 유일한 문제는 이전보다 더 많은 데이터를 가져와야하므로 어딘가에 오버플로가 발생하지만 어디에서 ?? 아마 여기

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(); 
     } 

    } 

    } 

답변

2

:

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

응답은 한 줄에 큰 JSON이 포함 된 경우

는, 당신은이 라인에 OutOfMemoryError가있을 수 있습니다. 수동으로 오는 응답을 확인하여이를 확인할 수 있습니다.

+1

가 어떻게 그것을 해결하는 것? – volk

0

나는이 코드 줄은 잘못된 생각 :

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 
     } 

대신 사용

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

희망이 도움이됩니다. 오류가 ReadLine 메서드 호출에 슬로우되었을은

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

이후 : 나는 당신이보고해야 볼 수 있습니다 무엇

+0

나는 여전히 같은 문제를 시도했다. 당신은 그것이 json이 너무 클 수 있다고 생각합니까? – volk

+0

작은 검색 후, 이것에 관한 스레드를 발견했습니다. 이것을 확인하십시오 : http://stackoverflow.com/questions/2886599/android-outofmemoryerror-loading-json-file – barisatbas

3

.

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

를 그리고 이에 대한 많은 예제가 있습니다

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

대신 내의 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) 

이 작업을 시도해야합니다.

편집 : 내 이전 프로젝트에서

다음 JSON이 매우 큰 경우

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

이것은 아닙니다. read 메소드의 최초의 인수는 byte []가 아니고 char []가 필요하기 때문에, 반드시 동작합니다. – volk

+0

제 편집 후 코드를보십시오. –

+0

예, 실제로 보았습니다. 죄송합니다 실제 문제는 내 "라인"변수가 문자열이기 때문에이 방법을 사용할 수 없다는 것입니다. 메신저가 없으면 readLine 만 적용 할 수 있습니다. – volk