James
James

Reputation: 1780

Garbage collection of private method call

I have a problem with memory use in my java app and for the life of me I can't understand why the garbage collector isn't sorting it out. The code is as follows:

public void foo() {
    for(int i=0; i<50000; i++) {
        bar(i);
    }
}

private void bar(int i) {
    LargeObject o = new LargeObject();
    ...
    dao.save(o);
}

My problem is that instances of LargeObject are not getting garbage collected - to identify this I've profiled with jprofiler and looked at the heap. LargeObject instances are never referenced by class variables, in fact they're not referenced anywhere outside of bar(). I'm clutching at straws I feel but could this be related to where the transactions start/end? I've tried changing bar() to public and annotating with Propogation.REQUIRES_NEW and also changing the annotation on foo() to Propogation.NEVER to no avail.

The code inside the dao looks like this:

public void save(LargeObject o) {
    hibernateTemplate.getSessionFactory().getCurrentSession().saveOrUpdate(o);
}

The garbage collection definitely runs as I see it's activity in jprofiler. foo() takes about 30 mins, bar() takes 36ms, garbage collection spikes roughly every 60 secs.

To answer the question why I know for sure they're not being garbage collected - nothing in the system references LargeObject yet I see instances of them on the heap increasing as foo() is executing.

Upvotes: 3

Views: 375

Answers (2)

Grooveek
Grooveek

Reputation: 10094

I'd add to @MaDa's answer that the loop might cause the burden on the unique session that had to cache all the Large Objects instances. You should consider either : flushing the session after save, or use a new session, or a cleared session for each LargeObject If they are not related

Reading the section on Batch Processing may help you understand your problem

Upvotes: 2

MaDa
MaDa

Reputation: 10762

Apparently they are referenced by your JPA provider (or whatever is hiding behind the dao.save()). You do let the reference outside, hence your control over it is lost. Whether you do it in a private/public method does not matter.

You might want to share more information about this "DAO".

Upvotes: 4

Related Questions