Alex Zaitsev
Alex Zaitsev

Reputation: 1781

android http request OutOfMemoryException

I have a method that do several http requests and it fails on the last request (for old devices only, e.g. here I used device with 20 Mb heap size).

My code:

private String request(String urlstr) throws IOException {
    HttpURLConnection conn = null;
    InputStream in = null;
    try {
        // constants
        URL url = new URL(urlstr);

        conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(TIMEOUT_SOCKET);
        conn.setConnectTimeout(TIMEOUT_CONNECTION);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setChunkedStreamingMode(8192);

        // open
        conn.connect();

        in = conn.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(in);
        ByteArrayBuffer baf = new ByteArrayBuffer(50);
        int read = 0;
        int bufSize = 512;
        byte[] buffer = new byte[bufSize];
        while (true) {
            read = bis.read(buffer);
            if (read == -1) {
                break;
            }
            baf.append(buffer, 0, read);
        }
        return new String(baf.toByteArray());
    } finally {
        if (conn != null)
            conn.disconnect();
        if (in != null)
            in.close();
    }
}

My logcat:

03-09 19:19:16.285: I/dalvikvm-heap(4595): Grow heap (frag case) to 11.921MB for 2097168-byte allocation
03-09 19:19:16.395: D/dalvikvm(4595): GC_FOR_MALLOC freed 0K, 54% free 9056K/19655K, external 833K/1345K, paused 84ms
03-09 19:19:16.555: D/dalvikvm(4595): GC_CONCURRENT freed 1024K, 60% free 8032K/19655K, external 833K/1345K, paused 6ms+7ms
03-09 19:19:16.695: D/dalvikvm(4595): GC_FOR_MALLOC freed 1K, 60% free 8032K/19655K, external 833K/1345K, paused 87ms
03-09 19:19:16.705: I/dalvikvm-heap(4595): Forcing collection of SoftReferences for 4194320-byte allocation
03-09 19:19:16.785: D/dalvikvm(4595): GC_FOR_MALLOC freed 2K, 60% free 8030K/19655K, external 833K/1345K, paused 84ms
03-09 19:19:16.785: E/dalvikvm-heap(4595): Out of memory on a 4194320-byte allocation.
03-09 19:19:16.785: I/dalvikvm(4595): "AsyncTask #4" prio=5 tid=12 RUNNABLE
03-09 19:19:16.785: I/dalvikvm(4595):   | group="main" sCount=0 dsCount=0 obj=0x4059f758 self=0x2bce60
03-09 19:19:16.785: I/dalvikvm(4595):   | sysTid=4632 nice=10 sched=0/0 cgrp=bg_non_interactive handle=2871192
03-09 19:19:16.785: I/dalvikvm(4595):   | schedstat=( 6902801505 2775817881 1301 )
03-09 19:19:16.785: I/dalvikvm(4595):   at org.apache.http.util.ByteArrayBuffer.expand(ByteArrayBuffer.java:~57)
03-09 19:19:16.785: I/dalvikvm(4595):   at org.apache.http.util.ByteArrayBuffer.append(ByteArrayBuffer.java:75)
03-09 19:19:16.785: I/dalvikvm(4595):   at any.travel.hotels.net.Search.request(Search.java:170)
03-09 19:19:16.785: I/dalvikvm(4595):   at any.travel.hotels.net.Search.run(Search.java:126)
03-09 19:19:16.785: I/dalvikvm(4595):   at any.travel.hotels.net.WebImpl.search(WebImpl.java:36)
03-09 19:19:16.785: I/dalvikvm(4595):   at any.travel.hotels.results.ResultsActivity$ResultsTask.doInBackground(ResultsActivity.java:161)
03-09 19:19:16.785: I/dalvikvm(4595):   at any.travel.hotels.results.ResultsActivity$ResultsTask.doInBackground(ResultsActivity.java:1)
03-09 19:19:16.785: I/dalvikvm(4595):   at android.os.AsyncTask$2.call(AsyncTask.java:185)
03-09 19:19:16.785: I/dalvikvm(4595):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
03-09 19:19:16.785: I/dalvikvm(4595):   at java.util.concurrent.FutureTask.run(FutureTask.java:138)
03-09 19:19:16.785: I/dalvikvm(4595):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
03-09 19:19:16.785: I/dalvikvm(4595):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
03-09 19:19:16.785: I/dalvikvm(4595):   at java.lang.Thread.run(Thread.java:1027)
03-09 19:19:16.796: E/dalvikvm(4595): Out of memory: Heap Size=19655KB, Allocated=8030KB, Bitmap Size=833KB, Limit=20480KB
03-09 19:19:16.796: E/dalvikvm(4595): Extra info: Footprint=19655KB, Allowed Footprint=19655KB, Trimmed=660KB
03-09 19:19:16.806: W/dalvikvm(4595): threadid=12: thread exiting with uncaught exception (group=0x400205a0)
03-09 19:19:16.816: E/AndroidRuntime(4595): FATAL EXCEPTION: AsyncTask #4
03-09 19:19:16.816: E/AndroidRuntime(4595): java.lang.RuntimeException: An error occured while executing doInBackground()
03-09 19:19:16.816: E/AndroidRuntime(4595):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
03-09 19:19:16.816: E/AndroidRuntime(4595):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
03-09 19:19:16.816: E/AndroidRuntime(4595):     at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
03-09 19:19:16.816: E/AndroidRuntime(4595):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
03-09 19:19:16.816: E/AndroidRuntime(4595):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
03-09 19:19:16.816: E/AndroidRuntime(4595):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
03-09 19:19:16.816: E/AndroidRuntime(4595):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
03-09 19:19:16.816: E/AndroidRuntime(4595):     at java.lang.Thread.run(Thread.java:1027)
03-09 19:19:16.816: E/AndroidRuntime(4595): Caused by: java.lang.OutOfMemoryError: (Heap Size=19655KB, Allocated=8030KB, Bitmap Size=833KB)
03-09 19:19:16.816: E/AndroidRuntime(4595):     at org.apache.http.util.ByteArrayBuffer.expand(ByteArrayBuffer.java:57)
03-09 19:19:16.816: E/AndroidRuntime(4595):     at org.apache.http.util.ByteArrayBuffer.append(ByteArrayBuffer.java:75)
03-09 19:19:16.816: E/AndroidRuntime(4595):     at any.travel.hotels.net.Search.request(Search.java:170)

It fails on the line baf.append(buffer, 0, read);.
Am I right if I say that responce is too large for this device? Maybe there is a way to fix this issue?

Upvotes: 0

Views: 347

Answers (1)

Merlevede
Merlevede

Reputation: 8170

Am I right if I say that responce is too large for this device?

Yes, this would be right.

Maybe there is a way to fix this issue?

Every time you execute this line baf.append(buffer, 0, read); the baf buffer is grown automatically until it runs out of memory. A possible work around, if it makes sense to your application, is as you download the information save it to disk. For example every time you've read 1MB of data, you commit it to a file on disk and free your baf variable to release all its memory.

Upvotes: 1

Related Questions