2

do like the below code, to read each line and perform a concatenation based on an input list listValues.

BufferedReader br = null;
StringBuilder sb = new StringBuilder("");
InputStream in = new FileInputStream(new File(file));
br = new BufferedReader(new InputStreamReader(in), 102400);
for (String input; (input= br.readLine()) != null;) {
    for (int i = 0; i < listValues.size(); i++) {
        sb.append(input.substring(1, 5));
    }
    map.put(sb.toString(), someOtherValue);
    sb.delete(0, sb.length());
}

Using the same StringBuilder for each iteration by setting deleting the contents each time. Still throws

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.lang.String.substring(Unknown Source)

What is the mistake I have done?

Edit: I have corrected as per Bathsheba's suggestion. But now throws,

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Unknown Source)
at java.lang.String.<init>(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)

at for (String input; (input= br.readLine()) != null;) What's the problem now?

Harbinger
  • 762
  • 2
  • 14
  • 36
  • possible duplicate of [memory leak issue on using java substring method](http://stackoverflow.com/questions/17359047/memory-leak-issue-on-using-java-substring-method) – Smutje Dec 17 '14 at 10:05
  • `input.substring(1, 5)` is the culprit... In older versions of Java, an array of the size of original String is created for the subString.. basically, too many objects. check [this](http://stackoverflow.com/questions/14161050/java-string-substring-method-potential-memory-leak) – TheLostMind Dec 17 '14 at 10:06
  • @TheLostMind Oops! could u suggest me how to handle this. I'm iterating the same hundreds of million times – Harbinger Dec 17 '14 at 10:08
  • What is the purpose of this method? What is `listValues`? What is `someOtherValue`? Perhaps if your example is more concrete we can advise on ways to avoid your memory problems. – Duncan Jones Dec 17 '14 at 10:10
  • @Harbinger - Check *Bathsheba's* answer.. :) – TheLostMind Dec 17 '14 at 10:11
  • I suggest you step through the code in your debugger to get a better understanding of what it is doing, your inner loop doesn't make any sense AFAIK. – Peter Lawrey Dec 17 '14 at 10:14
  • @TheLostMind could u pl see my updated question. I'm getting another exception different line – Harbinger Dec 17 '14 at 10:56

1 Answers1

2

Using substring within a tight loop is ill-advised since it will create many strings that may not be garbage collected until later.

A solution in your case would be to use charAt and append the chars to the StringBuilder instance:

for (int j = 1; j <= 5; ++j){ /*ToDo - check the loop bounds*/
    sb.append(input.charAt(j)); /*StringBuilder has an overload for `char` insertion*/
}
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Corrected as per yours. But, now throws Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOfRange(Unknown Source) at java.lang.String.(Unknown Source) at java.io.BufferedReader.readLine(Unknown Source) at java.io.BufferedReader.readLine(Unknown Source) at the for loop conditon. – Harbinger Dec 17 '14 at 10:35