• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Paul Clapham
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Roland Mueller
  • Piet Souris
Bartenders:

How do I create an Object Pool?

 
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a normal class called MyElement with 2 variables id,xml. In my program, there will be 30 million or so objects of this class created and my manager feels we should use an object pool for this class so that the performance improves.

This is my MyElement class:


Can someone please help me with creating an object pool for the above class?

Thanks.
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Object pooling is an old concept and if you need you can use java collection framework to implement an object pool.

But the best way is to optimize the JVM memory(heap) and GC options. This can cause to increase your JVM performance. but your coding style may also effect on this situation.

refer the following links for GC optimization.

http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp
http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
http://java.sun.com/performance/reference/whitepapers/5.0_performance.html
http://java.sun.com/performance/reference/whitepapers/tuning.html
http://java.sun.com/developer/technicalArticles/Programming/turbo/
 
v ray
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for those links .
Do you have any links to implement object pools using collections? Thats what I was asked to do.
 
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just googled it up and came across this reference. It also gives a sample implementation-

http://www.javaworld.com/javaworld/jw-06-1998/jw-06-object-pool.html?page=1

-Neelesh
 
v ray
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yeah, I did the same before I posted, however, that article doesnt address the needs I have.
It is using a connection pool as an example, while I have a simple class with 2 attributes, not very alike... I am supposed to use a collection to create a bunch of objects, and then people should be able to checkout and checkin objects...
 
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The connection pool in the example is just a pool that contains objects that connect to a database. Replace those objects with your own objects and you should have pretty much what you want.
Have a go at modifying the code and if you have problems come back and show us what you have got, and where it is not quite meeting your needs.
 
v ray
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This seems to be working:

 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Note that this pool is not thread safe; if you use this in a multithreaded program you're very likely to see ArrayIndexOutOfBoundsExceptions and even possibly hand out the same object from the pool more than once. Marking both methods as 'synchronized' would be sufficient to make this safe.

I'd also consider including a "debug mode"; if a flag is set, the pool checks whether an object is already in the pool before adding it.
 
v ray
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes you are right, thanks for the suggestion. I am indeed using threads in the program, so I will make the methods synchronized.
However, I do not understand how I would use "debug" mode here? Can you please give me an example?
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Add a member variable called "debug", initialized to "false". Then write returnToPool() something like this:



then provide a setDebug(boolean) method to set this flag. Then when you're testing your application, before you're in production, use setDebug(true), and it will tell you about errors in your application. In production, if weird stuff happens, you might want to turn it on again to check.
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One thing I didn't spot in here ... when you reuse an object from the pool you'll set all the fields to new values?

A BlockingQueue makes a dandy pool. You can make a fixed size pool to avoid out-of-control growth by pre-loading it with some number of objects. Then when the pool is empty the requester will wait for another thread to put an object back. You can make a growable pool like yours by testing for empty before trying a get. Then again, that approach won't be any shorter than what you have now for sure.
 
v ray
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, if I set the values of id and xml to null before I call the returnToPool() method, then the object will be ready to be used elsewhere.

Also, what you are saying is, the pool object would contain a predecided set of MyElement objects and when that runs out,
there is a wait until one object is returned back to the pool? This is possible, however, if you observe:

if ( end > 0 )
{
return pool.remove( end - 1 );
}

return new MyElement();

ie, when the pool does not contain any new objects in the pool, a new one is being created and returned.

What do you think of having a pre decided number of objects ready instead of having to create one object at a time or waiting for one object to be returned to the pool??
 
Neelesh A Korade
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ernest Friedman-Hill:
In production, if weird stuff happens, you might want to turn it on again to check.



Just want to understand the rationale behind using the debug mode only during the development. What would be the reason not to use it all the time, that is, even in production? Does it have too much of performance overhead? It seems to me that checking for the object to be already present in the queue before attempting to add it is a good defensive coding practice and I would prefer to have it in place even during production.

Just want to understand philosophy behind your suggestion. Could you please clraify it?

Thanks
Neelesh
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Neelesh A Korade:


Just want to understand the rationale behind using the debug mode only during the development.



Because List.contains() is an expensive call. Note that for little objects like this, the performance of even a trivial pool is unlikely to be better than just letting the garbage collector do its job -- it might even be worse! But for sure, adding the contains() call will make the performance much worse than using no pool at all.

If you could add an "in the pool" flag to each object, then you could do this check more cheaply; at that point, you're really fooling yourself though. The GC is pretty smart!
 
v ray
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually, I doubt if what I posted is a pool at all...Because, everytime a request for an object comes in, either it searches for an object in the list or creates a new one and returns it to the caller...
This is more like a "Factory" implementation?
Dont we need to initially have a predecided set of objects, and when the list containing those objects is empty, there is a wait for objects to return to the pool? This is my understanding of an object pool...The code I posted earlier was my manager's idea.
Critique?
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Some pools work that way, and some don't. A "factory" would hand out objects, but not allow them to be returned. A pool of an unlimited number of objects is sometimes called a "cache".

Pools that work the way you describe are commonly used with things like database connections where there's some reason for only having a finite number, due to limited resources. That isn't the case here.
 
v ray
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ernest Friedman-Hill:

Pools that work the way you describe are commonly used with things like database connections where there's some reason for only having a finite number, due to limited resources. That isn't the case here.



Yes, so a better way to do this would be to have a predecided set of objects ready like this:

 
Ernest Friedman-Hill
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It depends on what the goal is for having a pool is. What you're showing here is going to be S L O W compared to just creating and dropping the objects and letting the GC handle it. I thought the original goal was performance, and this is no way to go after that! The truth is that Sun's GC is optimized for dealing with lots of small short-lived objects, so pools rarely if ever help performance, and often hurt.

If you have a specific need to limit the number of simultaneously existing instances of this class, then you could do something like this; but you have to add some explicit wait() and notify() calls, and be very careful as you code to avoid deadlock, remembering that a call to get an instance might block waiting for any other thread to release one.
 
v ray
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ernest Friedman-Hill:
It depends on what the goal is for having a pool is. What you're showing here is going to be S L O W compared to just creating and dropping the objects and letting the GC handle it. I thought the original goal was performance, and this is no way to go after that! The truth is that Sun's GC is optimized for dealing with lots of small short-lived objects, so pools rarely if ever help performance, and often hurt.

If you have a specific need to limit the number of simultaneously existing instances of this class, then you could do something like this; but you have to add some explicit wait() and notify() calls, and be very careful as you code to avoid deadlock, remembering that a call to get an instance might block waiting for any other thread to release one.


Yes!! This is slow!
Instead of just writing:

object = new MyElement();

What I have been forced to right now is call the getOneElement() method which checks the List blah blah and returns one element which is then made use of and in the end, there is a returnToPool() call...which I feel is just slowing things down...
One thing though, If I didnt do this getOneElement() and returnToPool(), how do I make sure the object gets garbage collected? Because, I did run into a problem when I tried to create thousands of objects in this way.
Would setting the object variables' values back to null after I store what I need onto a List help the no longer needed object garbage collected?
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you're storing the objects in a list, then no, they won't be collected; neither, one would hope, would you return them to the pool under those circumstances. If you add an object to a List, then a reference to that actual object is added, and so the object is still being used.

If you're just putting the contents of the object into a list, then presumably the only references you have to the object are local, and those would go away soon enough, anyway. You don't have an unlimited number of those variables, probably just one.

If you're having memory issues, then it sounds like the problem isn't the pooled objects, but the XML strings themselves. Any reason why they have to be kept in core? Can you send them someplace (to a file, over the net) sooner?
 
v ray
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No, my question was, what if I did :

myele = new MyElement();
/*
do something
*/
list.add(myele);
myele.id = null;
myele.xml = null;

would the assignment to null once the object is stored in the list help the object "myele" get garbage collected?
And as for your question of why this is being done, well, some new columns are being added to a particular table in our database which contains 37 million records, and to populate those tables, another table's id and xml must be extracted, and later used to populate another table.
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you do what you've described, then you'll find later that the objects in the list have their member variables equal to null. That's because the object in the list is the same object in "myele". I'm sure this is not what you want!

So have you guys looked at possibly letting the database do all the work? With proper SQL skills, you can do all sorts of amazing stuff without ever pulling the data out of the database -- and often faster than you can do it in your Java code.
 
v ray
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh ok! Still, instead of trying to create thousands of objects at once, what if it is done in increments of 100 or 1000?

Also, maybe its not relevant to this thread, but let me explain what needs to be done.
Extra columns are being added to 2 tables, say table1 and table2(each table in different database accounts). To fill these empty columns, the xml values from another table which exists on a different database has to be used.

To fill up these extra columns, currently, the plan is:
1. Spool out all the data from the xml_hash table.
2. Spool out all data from table1 and table2.
3. create a load file for table1 by extracting relevant info from xml_hash +
spooled out table1 info.
4. created a load file for table2 by extracting relevant info from xml_hash+
spooled out table2 info.
5. dump the load file back onto the database.

As you can see, this will definitely be a lot of work as each of those tables have 30 million odd records and the production environment has to stop for considerable amount of time for this entire thing to be done.

Using plain sql in such a situation doesnt seem possible? I dont have an idea how it can be done even if its possible. Do you have any suggestions?
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Are we trying to improve memory use, or performance, or... ? You could improve the first of these, and perhaps as a result, the second, by splitting step 2 into two parts, one for each table; then doing steps 1, 2a, 3, (release table 1 data), 2b, 4, 5. That way there'd be less data in memory in total the whole time.
 
v ray
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Performance is the key here, as all the steps need to complete when the production is temporarily stopped to accomodate these changes.
And yes, we are spooling data out from table1 and table2 seperately. ie, run 2 programs( but they may run in parallel but since they point to different schemas, it shouldnt be a problem right?).
Memory (ie, storing out extracted information) will never really be a problem I think...the main task is to complete task 1-5 within the shortest possible time so that the production runs start back up asap.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic