1

I have to download around 6000 records into the sqlite database from a server. The records are present as JSON objects. While retrieving them using a BufferedReader, i get an error as out of memory bound exception. I have searched many sites but could not find an appropriate answer. Please suggest some best solution.

My code is:

URL url = new URL("myurl");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
//getting error here
line = in.readLine();
System.out.println(line);
JSONArray outerArray = (JSONArray) JSONSerializer.toJSON(line);
System.out.println("size : " + outerArray.size());

I got this Fatal Exception -

                 E/AndroidRuntime(616): java.lang.OutOfMemoryError: [memory exhausted]
4
  • task is calling in main thread or you have create Asyn class to call data in background ? Commented May 10, 2013 at 6:44
  • Where exactly are you getting this OutOfMemoryError? How much memory do you have? Commented May 10, 2013 at 6:49
  • Task is calling in main thread only.. Commented May 10, 2013 at 7:47
  • I am using emulator to run this code.. I am getting this error at BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); Commented May 10, 2013 at 7:48

3 Answers 3

1

Size of you downloading file is too much to hold in memory

Try doing like this

    // download the file
                InputStream input = new BufferedInputStream(url.openStream());
                OutputStream output = new FileOutputStream();

                byte data[] = new byte[1024];
                long total = 0;
                int count;
                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....

                    output.write(data, 0, count);
                }

                output.flush();
                output.close();
//

For more explanation see this

Also

You should use json streaming either with gson or jackson. With Jackson you can use a hybrid approach as well. This would reduce your memory consumption significantly as only the portion of json being parsed is loaded into memory.

https://sites.google.com/site/gson/gson-user-guide

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your reply.. But i am getting error as /sdcard/BarcodeScanner-debug.apk (Permission denied). I am a newbie to android.. Can u explain this issue..
I am getting error as permission denied.. What i have to do for that??
add <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> in manifest
Use FileOutputStream output=openFileOutput() ;
0

It seems you are trying to download the whole JSON Array in one go and that consume a lot of memory. Rather than doing readLine, try reading the input in a fixed amount chunk of buffer (eg: 1024), if that's enough to make one or more JSON Array, parse it. Then continue reading the next chunk. That way you're not blowing your memory space

Please note this method will only work if you can guarantee your JSON array element won't go past 1024 bytes. Otherwise try adjust this number accordingly / use adjustable data structure

2 Comments

Thanks.. But i have all those 6000 records in a single array... Can you help me..
That's fine. Where your program fail is when it tried to parse all 6000 items at once. Instead try processing them in small batches using method described in my answer
0

the heap memory may low provided to your app,

you need to register app for larger heap by entry in manifest,

<application android:largeHeap="true"> </application>

http://developer.android.com/guide/topics/manifest/application-element.html#largeHeap

1 Comment

Hi and welcome to SO. please add more details in your answer.

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.