1

I have a java heap space problem with hibernate since I add a modification in mi code. The program load information from a text file (2GB)

BufferedReader input = new BufferedReader(new FileReader(file));

while (line.compareTo(EOF) != 0) {
    //Load of infoObject, lots of parse information from the text file
    //Read lines of text using: line = input.readLine();

    getSession().save(infoObject);

    counter++;

    if (counter % 100 == 0) {
        getSession().flush();
        System.gc();
    }
}

This work great, now in case that the infoObject already exists in my db, I need to update the record, I use this:

BufferedReader input = new BufferedReader(new FileReader(file));

while (line.compareTo(EOF) != 0) {
    //Load of infoObject

    iObject infoObject_tmp = new iObject();
    infoObject_tmp.setNumAccount(numAccount);
    infoObject_tmp.setCloseDate(new Date("02/24/2011"));
    iObject infoObject_search = (iObject) getSession().load(iObject.class, infoObject_tmp);

    if (infoObject_search !=null){
        getSession().update(infoObject);
    }else{
        getSession().save(infoObject);
    }
    counter++;

    if (counter % 100 == 0) {
        getSession().flush();
        System.gc();
    }
}

FreeMemory:

  • Registry 1: 750283136.
  • Registry 10000: 648229608.
  • Registry 50000: 411171048.
  • Registry 100000: Java Heap Space.

How can i fix the java heap space problem? I know that the problem is when i check if the iObject exists or not.

2
  • 1
    So, what is your question, then? Commented May 16, 2011 at 14:18
  • How can i fix the java heap space problem? Commented May 16, 2011 at 14:28

3 Answers 3

3

you need a flush() followed by a clear(). flush() only pushes any pending updates to the database. clear() removes the objects from the session. you need to be careful with clear() though, because any other code which has a reference to an object which was in the session now has a "detached" object.

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

1 Comment

This improve the performance a lot, i'm running some test but i think that this solve my problem.
1

It's tough to tell what exactly is going on without seeing more of your code. It's also a bit confusing since your BufferedReader does not appear to be used.

That said, one possibility, given what it looks like you are doing, is that somewhere you are calling substring on some text input and keeping a reference to the String object that is returned as a result. For instance, you might be doing something like this:

List<String> allMySubstrings = new ArrayList<String>();
while((line = input.readLine()) != null){
  String mySubstring = line.subString(40, 42);
  // mySubstring still has a reference to the whole character array from line
  allMySubstrings.add(mySubstring);
}

You might think then that you will only have references to allMySubstrings and not every line that was read. However, because of the way subString is implemented, the resulting String object will have a reference to the entire original character array from line, not just the relevant substring. Garbage collection won't occur as you might expect as a result

If you are doing this, you can get around it by creating a new String object:

List<String> allMySubstrings = new ArrayList<String>();
while((line = input.readLine()) != null){
  String mySubstring = new String(line.subString(40, 42));
  allMySubstrings.add(mySubstring);
}

Note that this might be happening even if you do not explicitly call subString as common methods like split might be responsbile.

2 Comments

The problem is not reading the file, I take out the code that check if the account exists, and the memory performance is great.Any way i will check the strings, thank you!
@JMira Does the code checking if the account exists call split or subString on line and hold on to the results in some collection by any chance?
0

You declare BufferedReader input, but you never seem to use it. Could it be that the line Object that you refer to in the while loop is accessing the underlying File in a non-buffered way?

3 Comments

Yes, I don't put the whole code because is really big, but I use: line = input.readLine(); To access the text file.
Does the file contain line terminating characters (\n or \r)?
Yes, the problem is not reading the file, I take out the code that check if the account exists, and the memory performance is great.

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.