Avinash
Avinash

Reputation: 13257

Java String Memory Leak II

I have ask similar question before : Java String Memory Leak

But I was not sure what to ask:

Here is another piece of code I wrote:

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;


public class TestString {
    public static int  readLineXX(BufferedReader br) throws Exception {
            String s = br.readLine();
            if ( s == null ) return 0;
            return 1;
    }
    public static void main(String args[]) {
        while (true) {
        try {
            FileInputStream fstream = new FileInputStream("bigfile.txt");
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader  br = new BufferedReader(new InputStreamReader(in));
            while ( readLineXX (br)!= 0) {
                //System.out.print(".");
            }
            br.close();
            in.close();
            fstream.close();
        } catch (Exception e) {
        }       
    }
    }
}

Since the String in Java are Immutable, will the String s be garbage collected. I ran this code for long time using -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails options, It is running fine.

This is small snippet code of my main application where I think is leak and causing OOM. bigfile.txt is around 1GB.

Upvotes: 1

Views: 1524

Answers (4)

McDowell
McDowell

Reputation: 108859

There are no obvious memory leaks in the code.

Dump the heap with the -XX:+HeapDumpOnOutOfMemoryError JVM argument and analyse the results. (I'm assuming a Java 6 Hotspot JVM; if you're using another, there will likely be similar options.)

The DataInputStream is redundant; streams should be closed in finally blocks; but I don't see how such things could influence the errors you are reporting.

Upvotes: 0

rurouni
rurouni

Reputation: 2445

instead of

        FileInputStream fstream = new FileInputStream("bigfile.txt");
        DataInputStream in = new DataInputStream(fstream);
        BufferedReader  br = new BufferedReader(new InputStreamReader(in));

you could use

        BufferedReader  br = new BufferedReader(new FileReader("bigfile.txt"));

The only way to cause an OOME is having very long lines and limited memory. Are you using -Xmx options? Why are you using DataInputStream - is this binary or text data?

Upvotes: 1

Paul Wagland
Paul Wagland

Reputation: 29096

Yes, s will be garbage collected. Being immutable does not prevent it from being garbage collected, it just prevents it from being modified.

Note that br.readlLine() will potentially use a large amount of memory if the line is very large. For example, if your text file is 1gb without any line breaks, then it is quite possible for br.readLine() to consume 2gb, 1gb for the data that is read in, and then 1gb for the created string.

Upvotes: 4

Péter Török
Péter Török

Reputation: 116246

The Strings in your code can't cause memory leak, as they aren't referenced anywhere after returning from readLineXX, so all will get garbage collected. My suspects are rather the streams you are using. I can well imagine that for a 1GB input file the input streams can get pretty big.

One way to test this would be to cut your input file into 2 or more parts, and read each of them in turn. If the culprits are the streams, reading several smaller input files one by one should not cause a memory leak.

Upvotes: 1

Related Questions