I want to create large string from Arraylist of Strings.
The arraylist contains parts of a big text file.
original size of file is upto 5MB.
I have used following way to do it.
private void createFilefromChunks(ArrayList<String> stringval2) {
try {
System.gc();
Runtime.getRuntime().gc();
StringBuilder completeFile = new StringBuilder(150);
String val = null;
for (Iterator<String> iterator = stringval2.iterator(); iterator.hasNext(); ) {
val = (String) iterator.next();
completeFile.append(val);
}
System.out.println(completeFile.toString());
}
catch(OutOfMemoryError e) {
e.printStackTrace();
}
}
Above method works fine for small files upto 1MB,
but if my file size is increased to 4MB, it will give me an OutofmemoryException
Following is my Logcat details:
12-26 14:43:17.862: E/dalvikvm-heap(718): Out of memory on a 2100160-byte allocation.
12-26 14:43:17.862: I/dalvikvm(718): "main" prio=5 tid=1 RUNNABLE
12-26 14:43:17.862: I/dalvikvm(718): | group="main" sCount=0 dsCount=0 obj=0x40a14568 self=0x2a00b9e0
12-26 14:43:17.862: I/dalvikvm(718): | sysTid=718 nice=0 sched=0/0 cgrp=apps handle=1073870640
12-26 14:43:17.871: I/dalvikvm(718): | schedstat=( 16034835833 4219745479 1751 ) utm=1509 stm=94 core=0
12-26 14:43:17.871: I/dalvikvm(718): at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:~94)
12-26 14:43:17.871: I/dalvikvm(718): at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
12-26 14:43:17.871: I/dalvikvm(718): at java.lang.StringBuilder.append(StringBuilder.java:216)
12-26 14:43:17.871: I/dalvikvm(718): at com.example.splitbychapter.MainActivity.createFilefromChunks(MainActivity.java:160)
12-26 14:43:17.871: I/dalvikvm(718): at com.example.splitbychapter.MainActivity.readAsperChapter(MainActivity.java:120)
12-26 14:43:17.871: I/dalvikvm(718): at com.example.splitbychapter.MainActivity.onCreate(MainActivity.java:50)
12-26 14:43:17.881: I/dalvikvm(718): at android.app.Activity.performCreate(Activity.java:5008)
12-26 14:43:17.881: I/dalvikvm(718): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
12-26 14:43:17.881: I/dalvikvm(718): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
12-26 14:43:17.881: I/dalvikvm(718): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
12-26 14:43:17.881: I/dalvikvm(718): at android.app.ActivityThread.access$600(ActivityThread.java:130)
12-26 14:43:17.881: I/dalvikvm(718): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
12-26 14:43:17.890: I/dalvikvm(718): at android.os.Handler.dispatchMessage(Handler.java:99)
12-26 14:43:17.890: I/dalvikvm(718): at android.os.Looper.loop(Looper.java:137)
12-26 14:43:17.890: I/dalvikvm(718): at android.app.ActivityThread.main(ActivityThread.java:4745)
12-26 14:43:17.890: I/dalvikvm(718): at java.lang.reflect.Method.invokeNative(Native Method)
12-26 14:43:17.890: I/dalvikvm(718): at java.lang.reflect.Method.invoke(Method.java:511)
12-26 14:43:17.890: I/dalvikvm(718): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
12-26 14:43:17.890: I/dalvikvm(718): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-26 14:43:17.901: I/dalvikvm(718): at dalvik.system.NativeStart.main(Native Method)
12-26 14:43:17.901: W/System.err(718): java.lang.OutOfMemoryError
12-26 14:43:17.920: W/System.err(718): at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
12-26 14:43:17.920: W/System.err(718): at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
12-26 14:43:17.930: W/System.err(718): at java.lang.StringBuilder.append(StringBuilder.java:216)
12-26 14:43:17.930: W/System.err(718): at com.example.splitbychapter.MainActivity.createFilefromChunks(MainActivity.java:160)
12-26 14:43:17.940: W/System.err(718): at com.example.splitbychapter.MainActivity.readAsperChapter(MainActivity.java:120)
12-26 14:43:17.940: W/System.err(718): at com.example.splitbychapter.MainActivity.onCreate(MainActivity.java:50)
12-26 14:43:17.940: W/System.err(718): at android.app.Activity.performCreate(Activity.java:5008)
12-26 14:43:17.940: W/System.err(718): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
12-26 14:43:17.940: W/System.err(718): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
12-26 14:43:17.952: W/System.err(718): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
12-26 14:43:17.952: W/System.err(718): at android.app.ActivityThread.access$600(ActivityThread.java:130)
12-26 14:43:17.952: W/System.err(718): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
12-26 14:43:17.952: W/System.err(718): at android.os.Handler.dispatchMessage(Handler.java:99)
12-26 14:43:17.961: W/System.err(718): at android.os.Looper.loop(Looper.java:137)
12-26 14:43:17.961: W/System.err(718): at android.app.ActivityThread.main(ActivityThread.java:4745)
12-26 14:43:17.971: W/System.err(718): at java.lang.reflect.Method.invokeNative(Native Method)
12-26 14:43:17.980: W/System.err(718): at java.lang.reflect.Method.invoke(Method.java:511)
12-26 14:43:17.980: W/System.err(718): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
12-26 14:43:17.980: W/System.err(718): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-26 14:43:17.991: W/System.err(718): at dalvik.system.NativeStart.main(Native Method)
It grows my heap size upto 13MB as well and throws outOfMemoryError.
It throws error for StringBuilder at this line completeFile.append(val);
Any help is appreciated.
Thanks in advance.
You’ll be able to create larger strings if you know how big you need them to be to start with – you can create the
StringBuilderwith the exact capacity required, so it will never need to expand. It’s during expansion that the memory requirements are largest. So:Now the final conversion to
Stringmay still cause a problem – but if it does, there’s not a lot you’ll be able to do, to be honest.Also note that text in Java takes two bytes per character, so if this is being read from an ASCII file which is 5MB in size, you’ll end up with 10MB required for the string.
Do you have to put all of this into a single string? Given that you’re running on mobile devices (by the looks of it) you should really be trying to think of ways to use less memory if you can.