-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: High CPU usage on commit
PostPosted: Tue Jan 26, 2010 11:50 am 
Newbie

Joined: Tue Jan 19, 2010 6:57 am
Posts: 1
We have a system that creates and persists a reasonably large number of objects on a daily basis (up to 50,000). When the objects are initially created, they are persisted with the following code:

Code:
EntityTransaction trans = mgr.getTransaction();

try {
    trans.begin();
    mgr.merge(object);
    trans.commit();
}
catch (Exception e) {
    LOG.error("Error persisting updated object " + object.toString() + " to database. Error: " + e.getMessage(), e);
    trans.rollback();
}


(All persistence happens on a separate thread to the main application processing.)

When an object is updated, it is first cloned (a requirement of other parts of the system) and the same code as above called to persist the update to the database. The system is responsible for generating it's own Ids therefore the cloned objects have the same Id as the object being managed by the EntityManager.

When commit is called, we are seeing exceptionally high CPU usage; in fact as objects are created and updated quickly, the CPU usage frequently stays at 100%.

Connecting a profiler to the system indicates that the majority of the time is being spent in the method: org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(FlushEvent) which is called automatically by Hibernate following a commit.

I assume (but have been unable to confirm) that rather than simply writing the current change to the database, it is synchronizing all 50k managed objects which would go some way to explaining the high CPU usage.

Has anyone come across any similar issues and/or have any suggestions as to how avoid this problem?

Thanks

Steve


Top
 Profile  
 
 Post subject: Re: High CPU usage on commit
PostPosted: Wed Jan 27, 2010 4:00 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Hi,

please see
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3967

Please try the patch I propose in org.hibernate.engine.Cascade.java
and let me know if it improves the performance.
(if it does, please give a vote to HHH-3967)

thanks
Guenther


Top
 Profile  
 
 Post subject: Re: High CPU usage on commit
PostPosted: Thu Jan 28, 2010 3:09 am 
Expert
Expert

Joined: Tue Jun 16, 2009 3:36 am
Posts: 990
Hi,

after reviewing your post, I recognize that you are:
1. committing each of the 50.000 separately (= totally 50.000 commits = 50.000 flushes in commit-phase)
2. I guess you continue to work with the same persistence context without ever calling clear().
That would mean, that your persistent context is gradually increasing until it reaches 50.000 objects.
In summary you perform 50.000 flushes with having the last flushes scanning about 50.000 objects each time.

Solution:

1. Do commit more rarely.
2. Call clear after commit if possible, or detach the objects which you don't need anymore.

Generally:
Always examine if it is really necessary to have all object attached until the commit.
If yes, then avoid the use of flush were possible (consider that queries can call flush implicitly).
Otherwise you could call intermediate flush() + clear() keeping the persistent context always small.


Top
 Profile  
 
 Post subject: Re: High CPU usage on commit
PostPosted: Tue Apr 10, 2012 6:07 am 
Newbie

Joined: Tue Apr 10, 2012 5:38 am
Posts: 2
Location: Bangalore
pb00067 wrote:
Hi,

after reviewing your post, I recognize that you are:
1. committing each of the 50.000 separately (= totally 50.000 commits = 50.000 flushes in commit-phase)
2. I guess you continue to work with the same persistence context without ever calling clear().
That would mean, that your persistent context is gradually increasing until it reaches 50.000 objects.
In summary you perform 50.000 flushes with having the last flushes scanning about 50.000 objects each time.

Solution:

1. Do commit more rarely.
2. Call clear after commit if possible, or detach the objects which you don't need anymore.

Generally:
Always examine if it is really necessary to have all object attached until the commit.
If yes, then avoid the use of flush were possible (consider that queries can call flush implicitly).
Otherwise you could call intermediate flush() + clear() keeping the persistent context always small.


Hi All,
I am coming across a same issue of High CPU usage on creating an object and then committing to database for every object.
Some 700 objects are getting created on an average every time my method is called.
Now I am on the verge of committing only once after all those 700 objects are created.(i.e., I am bringing out the commit command out of the "for loop").
Will update when I get positive result on CPU usage.

Warm regards,
Nithin K N


Top
 Profile  
 
 Post subject: Re: High CPU usage on commit
PostPosted: Wed Apr 11, 2012 7:55 am 
Newbie

Joined: Tue Apr 10, 2012 5:38 am
Posts: 2
Location: Bangalore
nithin.keen wrote:
pb00067 wrote:
Hi,

after reviewing your post, I recognize that you are:
1. committing each of the 50.000 separately (= totally 50.000 commits = 50.000 flushes in commit-phase)
2. I guess you continue to work with the same persistence context without ever calling clear().
That would mean, that your persistent context is gradually increasing until it reaches 50.000 objects.
In summary you perform 50.000 flushes with having the last flushes scanning about 50.000 objects each time.

Solution:

1. Do commit more rarely.
2. Call clear after commit if possible, or detach the objects which you don't need anymore.

Generally:
Always examine if it is really necessary to have all object attached until the commit.
If yes, then avoid the use of flush were possible (consider that queries can call flush implicitly).
Otherwise you could call intermediate flush() + clear() keeping the persistent context always small.


[color=#0000BF]Hi All,
I am coming across a same issue of High CPU usage on creating an object and then committing to database for every object.
Some 700 objects are getting created on an average every time my method is called.
Now I am on the verge of committing only once after all those 700 objects are created.(i.e., I am bringing out the commit command out of the "for loop").
Will update when I get positive result on CPU usage.

Warm regards,
Nithin K N
I am still getting CPU spikes. I want to add up that after 700 objects being committed to db, there is a same number of commit on one more database table. I want to know does cutting this sequence of process bring down the CPU usage? I hope so!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.