Mariska
Mariska

Reputation: 1949

OutofMemory LinkedList Adding Error

I am trying to read from a txt file (book) and then add every line of it to a linkedlist. However, when I run the code, I got an outofmemory error at l.add(line);. Could you tell me what I am doing wrong with this code? Or, is there a better way to store the String values instead of LinkedList?

Thanks a lot!

public Book (String bookname) throws java.io.IOException{
    f = new FileReader(bookname);
    b = new BufferedReader(f);
    l = new LinkedList<String>();
    String line = b.readLine();
    while (line != null) {
        l.add(line);
    }
    b.close();
}

Upvotes: 1

Views: 1541

Answers (6)

Dead Programmer
Dead Programmer

Reputation: 12585

While loop never quits, because variable line is never null. Try this:

String line = "";
while ((line = b.readLine())!= null)
{
   l.add(line);
}
b.close();

Upvotes: 1

Ant&#39;s
Ant&#39;s

Reputation: 13811

I agree with mjg123. And be careful with the outofmemory expection. and i request you to have to look at this blog for more details of how to handle such situations Click here

Upvotes: 0

maverik
maverik

Reputation: 5606

Probably you should replace

while (line != null) {
    l.add(line);
}

with

while (line = b.readLine()) {
    l.add(line);
}

Upvotes: 2

esaj
esaj

Reputation: 16035

You are adding the same line over and over, until memory runs out:

String line = b.readLine();
while (line != null) {
    l.add(line);
}

See? The line-variable is read outside the loop, and never changes within the loop.

Upvotes: 2

Andrzej Doyle
Andrzej Doyle

Reputation: 103837

Quite simply, the memory required to store the strings (and everything else in your program) exceeded the total free memory available on the heap.

Other lists will have slightly different amounts of overhead, but realistically the memory requirements of the structure itself is likely to be insignificant compared to the data it contains. In other words, switching to a different list implementation might let you read a few more lines before falling over, but it won't solve the problem.

If you haven't increased the heap space of the java application, it might be running with fairly low defaults. In which case, you should consider providing the following command-line argument to your invocation of java:

-Xmx512m

(where the 512m implies 512 megabytes of heap space; you could use e.g. -Xmx2g or whatever else you feel is appropriate.)

On the other hand, if you're already running with a large heap (much larger than the total size of the Strings you want to hold in memory), this could point to a memory problem somewhere else. How many characters are there in the book? It will take at least twice that many bytes to store all of the lines, and probably 20% or so more than that to account for overhead. If your calculations indicate that your current heap space should be able to hold all of this data, there might be some trouble elsewhere. Otherwise, you now know what you'd need to increase you heap to as a minimum.

(As an aside, trying to process large amounts of input as a single batch can often run into memory issues - what if you want to process an 8GB text file? Often it's better to process smaller chunks sequentially, in some sort of stream. For example, if you wanted to uppercase every character and write it back out to a different file, you could do this a line at a time rather than reading the whole book into memory first.)

Upvotes: 0

Matthew Gilliard
Matthew Gilliard

Reputation: 9498

As others point out, you have created an infinite, memory-consuming loop. A common idiom for reading from a BufferedReader is:

String line;
while ( ( line = b.readLine() ) != null) {
    l.add(line);
}

I guess it is possible that the content of the book is just too large to fit into memory all at once anyway. You can increase the memory available to the JVM by using the Xmx argument, ie:

java -Xmx1G MyClass

The default value for this is 64 Mb, which isn't much these days.

Upvotes: 6

Related Questions