android http请求OutOfMemoryException

时间:2014-03-09 17:28:34

标签: android http out-of-memory

我有一个方法可以执行多个http请求,并且在最后一个请求中失败(仅适用于旧设备,例如此处我使用的堆大小为20 Mb的设备)。

我的代码:

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

我的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)

baf.append(buffer, 0, read);行失败 如果我说响应对于这个设备来说太大了,我是对的吗?也许有办法解决这个问题?

1 个答案:

答案 0 :(得分:1)

  

如果我说这个设备的响应太大,我是对的吗?

是的,这是对的。

  

也许有办法解决这个问题?

每次执行此行baf.append(buffer, 0, read);时,baf缓冲区会自动增长,直到内存不足为止。如果对您的应用程序有意义,可能的解决方法是在下载信息时将其保存到磁盘。例如,每次读取1MB数据时,将其提交到磁盘上的文件并释放baf变量以释放其所有内存。