2

My application was running fine about 5 days ago! Today, I try to run it, and its going absolutely nuts!

I'm getting this message in logcat before it finally throws the 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...

and then finally this error comes up:

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)

I THINK I narrowed it down to this block of code, but I don't know why it doesn't work! It was always working fine before. The only problem I can think of is that now it has to fetch more data than before, so somewhere an overflow is happening, but where??

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

    }

  }

3 Answers 3

3

What I can see you should look at this:

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

Since the error is trown at the readLine method call.

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)

You should try this:

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

And use read instead of readLine

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

There are many examples on this.

EDIT:

From my old project:

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;
}
Sign up to request clarification or add additional context in comments.

4 Comments

this doesn't necessarily work since the first argument of the read method needs a char[] rather than the byte[] .
yeah, I actually just looked at it. sorry the REAL problem is that I can't use this way because my "line" variable is a string. only the readLine is applicable here, unless im missing something
Well, you are assinging a value to 'line' which is to big and causes a exception. If the 'response' contains line breaks (\n) you could split the String and retreive your lines that way.
Do you mean that the value is too big for the type String?
2

Probably here:

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

If response contains big json in single line, then you can have a OutOfMemoryError on this line. You can verify this by checking what response is coming manually.

1 Comment

how would I fix it, if the JSON is very big?
0

I think this line of code is wrong :

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
      }

instead use :

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

Hope this helps.

2 Comments

I tried it, still the same problem. do you think it can be the json is just too big?
I don't think, but after a small search, I found a thread about this, check this out : stackoverflow.com/questions/2886599/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.