RE: New Object Pooling project
Howdy, Huh? Have you considered commons-pool? (http://jakarta.apache.org/commons/pool/) Yoav Shapira Millennium ChemInformatics -Original Message- From: David Boyer [mailto:[EMAIL PROTECTED] Sent: Saturday, December 27, 2003 3:02 PM To: [EMAIL PROTECTED] Subject: New Object Pooling project Hi all, I've released a beta of my Object Pooling software and it's freely available on my web site: http://web.bvu.edu/staff/david/pooling/ This is an extensible Object Pooling system that could be extending to handle pooling of just about any Object type. The initial release contains a full database connection pooling system. The main distinction between this pooling system and the others I can find is that there's no need to pre-configure the pools or use JNDI. This e-mail, including any attachments, is a confidential business communication, and may contain information that is confidential, proprietary and/or privileged. This e-mail is intended only for the individual(s) to whom it is addressed, and may not be saved, copied, printed, disclosed or used by anyone else. If you are not the(an) intended recipient, please immediately delete this e-mail from your computer system and notify the sender. Thank you. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
New Object Pooling project
Hi all, I've released a beta of my Object Pooling software and it's freely available on my web site: http://web.bvu.edu/staff/david/pooling/ This is an extensible Object Pooling system that could be extending to handle pooling of just about any Object type. The initial release contains a full database connection pooling system. The main distinction between this pooling system and the others I can find is that there's no need to pre-configure the pools or use JNDI.
RE: Object pooling (was: more about custam tag life cycle)
As Craig already said, it's not good to generalize. The only way to find out, is to test. (And always be prepared that the result may change in the next release of the vm) If the garbage collector works as you describe, it's quite easy to improve it in a way that it does the opposite of your conclusion: If the gc stores the object in generation buckets, and your pooled objects live long enough to be stored in the older generation they don't have to be copied which each run of the gc. This way you may win performance from pooling. Beside the performance, there may be other advantages of object pooling, like the reduction of memory defragmentation or the reduction of memory usage. I prefer to use pooled objects either for relative small number of long lived objects or for objects that are expensive to create, or immutable objects that consume some memory and are likely to be in use concurrently. In fact 'pooled objects' is sometimes an over technical phrase for things like the following: static final Integer cMinusOne = new Integer(-1); static final Integer cZero = new Integer(0); Or the usage of Boolean.TRUE instead of new Boolean(true) -Original Message- From: Will Hartung [mailto:[EMAIL PROTECTED]] Sent: Monday, February 03, 2003 11:42 PM To: Tomcat Users List Subject: Re: Object pooling (was: more about custam tag life cycle) From: Erik Price [EMAIL PROTECTED] Sent: Monday, February 03, 2003 2:16 PM Subject: Re: more about custam tag life cycle Are you saying that in general, object pooling is deprecated? In other words, it's always a bad idea, with the exception of DataSource type pools? As a design issue, Object Pooling is frowned upon with the modern garbage collectors because short lived objects are cheap. One of the original goals of Object Pooling was to put less strain on the GC by not creating lots of short term objects. With modern collectors, this is much less of an issue. For example, modern collectors during a GC will copy active objects. So, your GC time is relative to the number of active objects, rather than total allocated objects. For example, if you have 1000 active objects, and the GC will be copying them, then by the time the GC happens, it's essentially irrelevant whether you have 100 inactive objects or 1 inactive objects, your GC time will be the same. Therefore, the modern GCs are, if anything, punishing you for keeping objects around, rather than punishing you for simply creating objects. So, that means that whereas before the expense of an object was its creation, release, and GC, now the only expense is its creation and release. Of course, object creation is not free so as a general guideline it's better to minimize object creation in general. However, using an Object Pool is not necessarily prudent for generic objects, as you will be punished for saving them. Now, for objects that are especially expensive in their creation and are also inherently reusable, then pooling makes sense (and DB connections fall well into this category). All that being said, it does not mean the pooling within, say, a JSP code generator is necessarily bad. It can make the code a wee bit easier to create, as you simply surround Tag use (in this case) with getOrCreateTagFromPool and placeTagBackInPool. This puts the burden of tracking used Tags and what not upon the JSP runtime, rather than the compiler. This is not a big deal in this case because the Object Pool could have a short life span and probably won't survive a GC. Anyway, in summary, as a general rule Object Pools are more expensive than they are worth with modern GCs. However, with a better understanding of them, you may find scenarios where they are worth utilizing. Regards, Will Hartung ([EMAIL PROTECTED]) - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: Object pooling (was: more about custam tag life cycle)
On Tue, 2003-02-04 at 00:34, Ralph Einfeldt wrote: I prefer to use pooled objects either for relative small number of long lived objects or for objects that are expensive to create, or immutable objects that consume some memory and are likely to be in use concurrently. Pooling is actually a great thing to do with immutable objects. The object is immutable, so it is in a correct state from construction to garbage collection. Also, because it is immutable, it can be shared by multiple threads and other objects. That's great. If tags were immutable, then pooling might be a very cool feature. Unfortunately, tags have the worst of both worlds: they are mutable, and they are pooled. This means they are difficult to use correctly because they are trying to work like C++ things instead of like Java things. - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
RE: Object pooling (was: more about custam tag life cycle)
I prefer to use pooled objects either for relative small number of long lived objects or for objects that are expensive to create, or immutable objects that consume some memory and are likely to be in use concurrently. And what you think about objects that are created millions of times and pratically do not change any of its properties? I have some objects that deal with database queries (I store my SQL queries in a XML file... long story), so I have one of these objects created for each query executed in my database... I was thinking about pooling these guys, but I'm not sure. -- Felipe Schnack Analista de Sistemas [EMAIL PROTECTED] Cel.: (51)91287530 Linux Counter #281893 Centro Universitário Ritter dos Reis http://www.ritterdosreis.br [EMAIL PROTECTED] Fone/Fax.: (51)32303341 - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Object pooling (was: more about custam tag life cycle)
From: Erik Price [EMAIL PROTECTED] Sent: Monday, February 03, 2003 2:16 PM Subject: Re: more about custam tag life cycle Are you saying that in general, object pooling is deprecated? In other words, it's always a bad idea, with the exception of DataSource type pools? As a design issue, Object Pooling is frowned upon with the modern garbage collectors because short lived objects are cheap. One of the original goals of Object Pooling was to put less strain on the GC by not creating lots of short term objects. With modern collectors, this is much less of an issue. For example, modern collectors during a GC will copy active objects. So, your GC time is relative to the number of active objects, rather than total allocated objects. For example, if you have 1000 active objects, and the GC will be copying them, then by the time the GC happens, it's essentially irrelevant whether you have 100 inactive objects or 1 inactive objects, your GC time will be the same. Therefore, the modern GCs are, if anything, punishing you for keeping objects around, rather than punishing you for simply creating objects. So, that means that whereas before the expense of an object was its creation, release, and GC, now the only expense is its creation and release. Of course, object creation is not free so as a general guideline it's better to minimize object creation in general. However, using an Object Pool is not necessarily prudent for generic objects, as you will be punished for saving them. Now, for objects that are especially expensive in their creation and are also inherently reusable, then pooling makes sense (and DB connections fall well into this category). All that being said, it does not mean the pooling within, say, a JSP code generator is necessarily bad. It can make the code a wee bit easier to create, as you simply surround Tag use (in this case) with getOrCreateTagFromPool and placeTagBackInPool. This puts the burden of tracking used Tags and what not upon the JSP runtime, rather than the compiler. This is not a big deal in this case because the Object Pool could have a short life span and probably won't survive a GC. Anyway, in summary, as a general rule Object Pools are more expensive than they are worth with modern GCs. However, with a better understanding of them, you may find scenarios where they are worth utilizing. Regards, Will Hartung ([EMAIL PROTECTED]) - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Object pooling (was: more about custam tag life cycle)
Will Hartung wrote: From: Erik Price [EMAIL PROTECTED] Sent: Monday, February 03, 2003 2:16 PM Subject: Re: more about custam tag life cycle Are you saying that in general, object pooling is deprecated? In other words, it's always a bad idea, with the exception of DataSource type pools? As a design issue, Object Pooling is frowned upon with the modern garbage collectors because short lived objects are cheap. One of the original goals of Object Pooling was to put less strain on the GC by not creating lots of short term objects. Thanks. Someday I will have to learn more about garbage collection. Erik - To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
Re: Object Pooling
Yes, there's a big difference between caching and pooling. Pooling is a case where you have several, essentially, identical object that you would like to reuse whereas caching is where you have several distinct objects that you would like to access faster than normal. A simple cache is really trivial to set up, however it is up to you to decide whether a trivial cache will be effective for you. If your data is truly static (i.e. you are comfortable in restarting Tomcat to reset your cache), then the simplest way to create a cache is to use a Singleton object that encapsulates access to the cache through a HashMap. The trick, however, is to ensure that you initialize the Singleton cache during the start up of the Tomcat container (using a load-on-startup tag in the web.xml). By doing this you do not have to worry about threading issues, as the servlets init() methods are called indvidually, and sequentially before request processing starts. This means no synchronization overhead during runtime. Once intialized, you simply fetch the objects out of the HashMap for your application. Of course, follow the other suggestions and ensure that this is really a bottleneck in you application. If your data is not that static, then the cache suddenly becomes much more complex in dealing with issues like stale data and refresh. Top that complexity with the fact that a decent database with ample memory will also cache the data as well, and you must consider how much benefit the added complexity will give you. Regards, Will Hartung ([EMAIL PROTECTED]) - Original Message - From: Felipe Schnack [EMAIL PROTECTED] To: Tomcat Users List [EMAIL PROTECTED] Sent: Monday, December 23, 2002 1:10 PM Subject: RE: Object Pooling Yes... I guess I didn't know the difference between caching and pooling. Anyway, if now I got the idea, I should use a cache for the second case, ok. There is a good opensource implementation around? And in the first case, as my objects are not thread safe maybe I should use a pool, shouldn't I? Or maybe the effort doesn't pay? -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: Object Pooling
I'm rewriting this reply, maybe I wasn't clear enough :-) My application have two types of objects that are constantly created and destroyed. I believe that they could be pooled in some way (maybe using commons pooling package. These types are: 1- Objects that handle user interaction. Basically they are the objects that actually implement tasks that would be otherwise done using servlets. In pratice, JSPs send data to them (like html form data) and they process it and return the results to the browser. These ones i'm not sure (yet) if I should pool. I'm not familiar with Struts, I would like to know how it does that. Someone can give me some tips? 2- These I strongly believe I should cache, and I'm already caching them, but with an solution designed by myself. I have some database tables that stores user permissions for the application. Basically, there are two tables that stores an module ID and who can access it (by user id, user profession, etc). I was thinking about loading all of them in memory at system startup and update them from time to time (or using Observable interfaces)? What do you think about it? You may want to pursue object pooling, but the prevailing conventional wisdom is that it's not really necessary. Object Pooling is important for objects that are particularly expensive to create (due to internal object requirements, like connecting to external resources) and is not really appropriate simply for lots of standard generic Java objects. While instantiating an object certainly has some cost, creating and tossing them away is not overly expensive. Now, perhaps you've done some testing and found these particular objects to be problematic, but it seems to me to be a toss up between simply creating new objects versus using an object pool. Any object pool is necessarily going to at least have synchronization issues tied to it which may in the end cost more overall than creating and disposing of the objects. Modern GCs are pretty good about tossing away temporary objects. Now, if you're perhaps doing some things in a tight loop, then maybe simply a judicious use of the objects would be better. Say, rather than using a generic object pool, simply creating the few necessary instances for your loop before hand and reusing them explicity within the loop rather than constantly creating new ones. -- Felipe Schnack Analista de Sistemas [EMAIL PROTECTED] Cel.: (51)91287530 Linux Counter #281893 Centro Universitário Ritter dos Reis http://www.ritterdosreis.br [EMAIL PROTECTED] Fone/Fax.: (51)32303341 -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: Object Pooling
-Original Message- From: Felipe Schnack [mailto:[EMAIL PROTECTED]] Sent: Monday, December 23, 2002 2:52 PM To: Tomcat Users List Subject: Re: Object Pooling I'm rewriting this reply, maybe I wasn't clear enough :-) My application have two types of objects that are constantly created and destroyed. I believe that they could be pooled in some way (maybe using commons pooling package. These types are: 1- Objects that handle user interaction. Basically they are the objects that actually implement tasks that would be otherwise done using servlets. In pratice, JSPs send data to them (like html form data) and they process it and return the results to the browser. These ones i'm not sure (yet) if I should pool. I'm not familiar with Struts, I would like to know how it does that. Someone can give me some tips? If you're talking about Struts actions, they're not pooled, exactly. One instance of each action is created on demand and cached indefinitely. Actions need to be written so that a single instance can be used by multiple threads simultaneously. That way, you can just instantiate it once and no pooling is necessary. 2- These I strongly believe I should cache, and I'm already caching them, but with an solution designed by myself. I have some database tables that stores user permissions for the application. Basically, there are two tables that stores an module ID and who can access it (by user id, user profession, etc). I was thinking about loading all of them in memory at system startup and update them from time to time (or using Observable interfaces)? There's a difference between caching and pooling. It sounds more like you're talking about using caches (e.g., storing instances that hold copies of external data) which is often a good idea. Pools are stores of unused instances that client code can borrow an instance from for some period of time, and then return the instance when it's done. It sounds like caching may be a good idea in this case, especially if you don't expect the data to change much and all changes will be going through the cached objects. If some other program may be writing updates directly to the database, however, you'll need to worry about your cached data going out of date. -- Tim Moore / Blackboard Inc. / Software Engineer 1899 L Street, NW / 5th Floor / Washington, DC 20036 Phone 202-463-4860 ext. 258 / Fax 202-463-4863 What do you think about it? You may want to pursue object pooling, but the prevailing conventional wisdom is that it's not really necessary. Object Pooling is important for objects that are particularly expensive to create (due to internal object requirements, like connecting to external resources) and is not really appropriate simply for lots of standard generic Java objects. While instantiating an object certainly has some cost, creating and tossing them away is not overly expensive. Now, perhaps you've done some testing and found these particular objects to be problematic, but it seems to me to be a toss up between simply creating new objects versus using an object pool. Any object pool is necessarily going to at least have synchronization issues tied to it which may in the end cost more overall than creating and disposing of the objects. Modern GCs are pretty good about tossing away temporary objects. Now, if you're perhaps doing some things in a tight loop, then maybe simply a judicious use of the objects would be better. Say, rather than using a generic object pool, simply creating the few necessary instances for your loop before hand and reusing them explicity within the loop rather than constantly creating new ones. -- Felipe Schnack Analista de Sistemas [EMAIL PROTECTED] Cel.: (51)91287530 Linux Counter #281893 Centro Universitário Ritter dos Reis http://www.ritterdosreis.br [EMAIL PROTECTED] Fone/Fax.: (51)32303341 -- To unsubscribe, e-mail: mailto:tomcat-user- [EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: Object Pooling
Yes... I guess I didn't know the difference between caching and pooling. Anyway, if now I got the idea, I should use a cache for the second case, ok. There is a good opensource implementation around? And in the first case, as my objects are not thread safe maybe I should use a pool, shouldn't I? Or maybe the effort doesn't pay? On Mon, 2002-12-23 at 18:52, Tim Moore wrote: -Original Message- From: Felipe Schnack [mailto:[EMAIL PROTECTED]] Sent: Monday, December 23, 2002 2:52 PM To: Tomcat Users List Subject: Re: Object Pooling I'm rewriting this reply, maybe I wasn't clear enough :-) My application have two types of objects that are constantly created and destroyed. I believe that they could be pooled in some way (maybe using commons pooling package. These types are: 1- Objects that handle user interaction. Basically they are the objects that actually implement tasks that would be otherwise done using servlets. In pratice, JSPs send data to them (like html form data) and they process it and return the results to the browser. These ones i'm not sure (yet) if I should pool. I'm not familiar with Struts, I would like to know how it does that. Someone can give me some tips? If you're talking about Struts actions, they're not pooled, exactly. One instance of each action is created on demand and cached indefinitely. Actions need to be written so that a single instance can be used by multiple threads simultaneously. That way, you can just instantiate it once and no pooling is necessary. 2- These I strongly believe I should cache, and I'm already caching them, but with an solution designed by myself. I have some database tables that stores user permissions for the application. Basically, there are two tables that stores an module ID and who can access it (by user id, user profession, etc). I was thinking about loading all of them in memory at system startup and update them from time to time (or using Observable interfaces)? There's a difference between caching and pooling. It sounds more like you're talking about using caches (e.g., storing instances that hold copies of external data) which is often a good idea. Pools are stores of unused instances that client code can borrow an instance from for some period of time, and then return the instance when it's done. It sounds like caching may be a good idea in this case, especially if you don't expect the data to change much and all changes will be going through the cached objects. If some other program may be writing updates directly to the database, however, you'll need to worry about your cached data going out of date. -- Tim Moore / Blackboard Inc. / Software Engineer 1899 L Street, NW / 5th Floor / Washington, DC 20036 Phone 202-463-4860 ext. 258 / Fax 202-463-4863 What do you think about it? You may want to pursue object pooling, but the prevailing conventional wisdom is that it's not really necessary. Object Pooling is important for objects that are particularly expensive to create (due to internal object requirements, like connecting to external resources) and is not really appropriate simply for lots of standard generic Java objects. While instantiating an object certainly has some cost, creating and tossing them away is not overly expensive. Now, perhaps you've done some testing and found these particular objects to be problematic, but it seems to me to be a toss up between simply creating new objects versus using an object pool. Any object pool is necessarily going to at least have synchronization issues tied to it which may in the end cost more overall than creating and disposing of the objects. Modern GCs are pretty good about tossing away temporary objects. Now, if you're perhaps doing some things in a tight loop, then maybe simply a judicious use of the objects would be better. Say, rather than using a generic object pool, simply creating the few necessary instances for your loop before hand and reusing them explicity within the loop rather than constantly creating new ones. -- Felipe Schnack Analista de Sistemas [EMAIL PROTECTED] Cel.: (51)91287530 Linux Counter #281893 Centro Universitário Ritter dos Reis http://www.ritterdosreis.br [EMAIL PROTECTED] Fone/Fax.: (51)32303341 -- To unsubscribe, e-mail: mailto:tomcat-user- [EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- Felipe Schnack Analista de Sistemas [EMAIL PROTECTED] Cel.: (51)91287530 Linux Counter #281893 Centro Universitário Ritter dos Reis http://www.ritterdosreis.br [EMAIL PROTECTED] Fone/Fax.: (51)32303341 -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED
RE: Object Pooling
-Original Message- From: Felipe Schnack [mailto:[EMAIL PROTECTED]] Sent: Monday, December 23, 2002 4:11 PM To: Tomcat Users List Subject: RE: Object Pooling Yes... I guess I didn't know the difference between caching and pooling. Anyway, if now I got the idea, I should use a cache for the second case, ok. There is a good opensource implementation around? Well, first I'd ask whether the custom implementation you said you already have is up to the task. If you already have something that works, why replace it? If you do need to replace it, then the choice of what to replace it with will be largely determined by what you need from it. You can use EJBs as a database cache, or one of the many object-relational mapping tools like Jakarta OJB. Really, it's hard to pick one tool that would work for all situations, and this is starting to get a little off-topic for this list. It's probably worth taking a look at OJB as a starting point (http://jakarta.apache.org/ojb/objectcache.html). And in the first case, as my objects are not thread safe maybe I should use a pool, shouldn't I? Or maybe the effort doesn't pay? It's going to depend greatly on what happens when these objects are instantiated. If they do something very expensive every time (load a file, make a DB query, etc) and it would be possible to do that initialization just once, rather than once per request, then pooling might be helpful. If you're just creating a new object and not doing anything resource-intensive, then pooling probably won't gain you much. As with any optimization, it's best to actually measure performance before changing anything to make sure there's really a bottleneck, and then measure again after changing (if you decide to do so) to make sure you're really improving it. Cheers, -- Tim Moore / Blackboard Inc. / Software Engineer 1899 L Street, NW / 5th Floor / Washington, DC 20036 Phone 202-463-4860 ext. 258 / Fax 202-463-4863 On Mon, 2002-12-23 at 18:52, Tim Moore wrote: -Original Message- From: Felipe Schnack [mailto:[EMAIL PROTECTED]] Sent: Monday, December 23, 2002 2:52 PM To: Tomcat Users List Subject: Re: Object Pooling I'm rewriting this reply, maybe I wasn't clear enough :-) My application have two types of objects that are constantly created and destroyed. I believe that they could be pooled in some way (maybe using commons pooling package. These types are: 1- Objects that handle user interaction. Basically they are the objects that actually implement tasks that would be otherwise done using servlets. In pratice, JSPs send data to them (like html form data) and they process it and return the results to the browser. These ones i'm not sure (yet) if I should pool. I'm not familiar with Struts, I would like to know how it does that. Someone can give me some tips? If you're talking about Struts actions, they're not pooled, exactly. One instance of each action is created on demand and cached indefinitely. Actions need to be written so that a single instance can be used by multiple threads simultaneously. That way, you can just instantiate it once and no pooling is necessary. 2- These I strongly believe I should cache, and I'm already caching them, but with an solution designed by myself. I have some database tables that stores user permissions for the application. Basically, there are two tables that stores an module ID and who can access it (by user id, user profession, etc). I was thinking about loading all of them in memory at system startup and update them from time to time (or using Observable interfaces)? There's a difference between caching and pooling. It sounds more like you're talking about using caches (e.g., storing instances that hold copies of external data) which is often a good idea. Pools are stores of unused instances that client code can borrow an instance from for some period of time, and then return the instance when it's done. It sounds like caching may be a good idea in this case, especially if you don't expect the data to change much and all changes will be going through the cached objects. If some other program may be writing updates directly to the database, however, you'll need to worry about your cached data going out of date. -- Tim Moore / Blackboard Inc. / Software Engineer 1899 L Street, NW / 5th Floor / Washington, DC 20036 Phone 202-463-4860 ext. 258 / Fax 202-463-4863 What do you think about it? You may want to pursue object pooling, but the prevailing conventional wisdom is that it's not really necessary. Object Pooling is important for objects that are particularly expensive to create (due to internal object requirements, like connecting to external resources) and is not really
Re: Object Pooling
On Mon, 2002-12-23 at 11:52, Felipe Schnack wrote: My application have two types of objects that are constantly created and destroyed. I believe that they could be pooled in some way (maybe using commons pooling package. These types are: 1- Objects that handle user interaction. Basically they are the objects that actually implement tasks that would be otherwise done using servlets. In pratice, JSPs send data to them (like html form data) and they process it and return the results to the browser. These ones i'm not sure (yet) if I should pool. I'm not familiar with Struts, I would like to know how it does that. Someone can give me some tips? 2- These I strongly believe I should cache, and I'm already caching them, but with an solution designed by myself. I have some database tables that stores user permissions for the application. Basically, there are two tables that stores an module ID and who can access it (by user id, user profession, etc). I was thinking about loading all of them in memory at system startup and update them from time to time (or using Observable interfaces)? I don't fully understand how your application is structured, but here are my general thoughts on pooling and caching of objects. Way back in Java 1.0, creating objects was expensive, so people had the idea of having pools of pre-created objects ready to go, which could be reinitialized with new data. Reinitializing an object was a big performance win over constructing a new object. Times have changed since then. For ordinary objects, creating new objects from scratch is very very fast. I read somewhere that an ordinary PII machine can create something like a million small ordinary objects per second, and can GC them at the same rate. There is absolutely no reason to pool these types of objects. There are, however, objects which are still expensive to create and should be pooled. The obvious examples are database connections, threads, and possibly (possibly) direct buffers. But outside of those areas, don't pool objects. One big reason to not pool objects is for correctness and security. If you are using pooled objects, you have to do lots of checking at every step to see if the object is properly initialized, and to make sure it contains no left-over data. What if the object represents a user session, and somehow users were able to get into other users' sessions because an old object got reused without proper reinitialization? That could be a big problem. We moved from C++ to Java to avoid having to worry about storage management bugs like that. It is best to make objects immutable. This means that after the object is constructed, no externally visible changes to the object can ever occur for the lifetime of the object. Immutable objects are much safer and more correct. This may be counter-intuitive, but immutable objects can also lead to better program performance because their internal data structure can be shared. This also helps on debugging. The object is in a valid state AT ALL TIMES in its existence. Making all the instance members of an object private final really helps catch a lot of bugs at compile time. Caching, on the other hand, is a totally different. Caching objects is definitely a good way to go, especially in web applications where objects often have to be used several times in one page output, and they often come from some kind of expensive persistent storage like a db. Go ahead and cache. Put your cache in the servelt context, for instance. Again, make the objects in your cache immutable if possible. This has many advantages, including correctness, performance and thread safety. -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
RE: Object Pooling
On Mon, 23 Dec 2002, Tim Moore wrote: Date: Mon, 23 Dec 2002 17:07:49 -0500 From: Tim Moore [EMAIL PROTECTED] Reply-To: Tomcat Users List [EMAIL PROTECTED] To: Tomcat Users List [EMAIL PROTECTED] Subject: RE: Object Pooling -Original Message- From: Felipe Schnack [mailto:[EMAIL PROTECTED]] Sent: Monday, December 23, 2002 4:11 PM To: Tomcat Users List Subject: RE: Object Pooling Yes... I guess I didn't know the difference between caching and pooling. Anyway, if now I got the idea, I should use a cache for the second case, ok. There is a good opensource implementation around? Well, first I'd ask whether the custom implementation you said you already have is up to the task. If you already have something that works, why replace it? If you do need to replace it, then the choice of what to replace it with will be largely determined by what you need from it. You can use EJBs as a database cache, or one of the many object-relational mapping tools like Jakarta OJB. Really, it's hard to pick one tool that would work for all situations, and this is starting to get a little off-topic for this list. It's probably worth taking a look at OJB as a starting point (http://jakarta.apache.org/ojb/objectcache.html). And in the first case, as my objects are not thread safe maybe I should use a pool, shouldn't I? Or maybe the effort doesn't pay? It's going to depend greatly on what happens when these objects are instantiated. If they do something very expensive every time (load a file, make a DB query, etc) and it would be possible to do that initialization just once, rather than once per request, then pooling might be helpful. If you're just creating a new object and not doing anything resource-intensive, then pooling probably won't gain you much. As with any optimization, it's best to actually measure performance before changing anything to make sure there's really a bottleneck, and then measure again after changing (if you decide to do so) to make sure you're really improving it. More generally, I would first try to determine whether the object creation / GC overhead is really significant to your app's overall performance before investing too much time in worrying how to pool it. Using a 1.4 or later JDK, plus turning on incremental garbage collection, seems to make the overhead of per-request object creations to be pretty much irrelevant for lots of web apps. If you determine that you do need pooling, you should consider commons-pool from Jakarta. That's what Tomcat already uses inside the database connection pooling code, and commons-pool.jar is already included with Tomcat, so you don't even need to go grab it. Online documentation is available at: http://jakarta.apache.org/commons/pool/ Craig McClanahan -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: object pooling
Well... thank you for the educative answer :-) My application have to types of objects that are constantly created and destroyed 1- Objects that handle user interaction. Basically they are the objects that delegates tasks that would be otherwise done using servlets. JSPs send data to them (like html form data) and they process it and return the results to the browser. These ones i'm not sure (yet) if I should cache. I'm not familiar with Struts, I would like to know how it does that. Someone can give me some tips? 2- These I strongly believe I should cache. I have some database tables that stores user permissions on the application. Basically, there are two tables that stores an module ID and who can access it (by user id, user profession, etc). As these objects are implemented now, each visited page does and query to the database to check permissions... that seems quite bad IMHO. Maybe I could simply load all of them in memory at system startup and update them from time to time (or using Observable interfaces)? Suggestions? You may want to pursue object pooling, but the prevailing conventional wisdom is that it's not really necessary. Object Pooling is important for objects that are particularly expensive to create (due to internal object requirements, like connecting to external resources) and is not really appropriate simply for lots of standard generic Java objects. While instantiating an object certainly has some cost, creating and tossing them away is not overly expensive. Now, perhaps you've done some testing and found these particular objects to be problematic, but it seems to me to be a toss up between simply creating new objects versus using an object pool. Any object pool is necessarily going to at least have synchronization issues tied to it which may in the end cost more overall than creating and disposing of the objects. Modern GCs are pretty good about tossing away temporary objects. Now, if you're perhaps doing some things in a tight loop, then maybe simply a judicious use of the objects would be better. Say, rather than using a generic object pool, simply creating the few necessary instances for your loop before hand and reusing them explicity within the loop rather than constantly creating new ones. Regards, Will Hartung ([EMAIL PROTECTED]) Felipe Schnack Analista de Sistemas [EMAIL PROTECTED] Cel.: (51)91287530 Linux Counter #281893 Faculdade Ritter dos Reis www.ritterdosreis.br [EMAIL PROTECTED] Fone/Fax.: (51)32303328 -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
object pooling
Maybe I should be posting this on a commons maillist or something? Well, the problem is that I have some objects that I'm instantiaing tons of times in my application, and so, I would like to pool them. There is somewhere a good dummies guide to commons-pool jar? The javadocs aren't enough :-) -- Felipe Schnack Analista de Sistemas [EMAIL PROTECTED] Cel.: (51)91287530 Linux Counter #281893 Centro Universitário Ritter dos Reis http://www.ritterdosreis.br [EMAIL PROTECTED] Fone/Fax.: (51)32303341 -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: object pooling
On Fri, 2002-12-20 at 11:00, Felipe Schnack wrote: Maybe I should be posting this on a commons maillist or something? Well, the problem is that I have some objects that I'm instantiaing tons of times in my application, and so, I would like to pool them. There is somewhere a good dummies guide to commons-pool jar? The javadocs aren't enough :-) Have you actually profiled your application to see if this is really having a performance impact? If you are using the latest Java (1.41) object creation is very very fast, with certain exceptions, such as very large objects, or special objects like direct buffers or threads. -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: object pooling
You may want to pursue object pooling, but the prevailing conventional wisdom is that it's not really necessary. Object Pooling is important for objects that are particularly expensive to create (due to internal object requirements, like connecting to external resources) and is not really appropriate simply for lots of standard generic Java objects. While instantiating an object certainly has some cost, creating and tossing them away is not overly expensive. Now, perhaps you've done some testing and found these particular objects to be problematic, but it seems to me to be a toss up between simply creating new objects versus using an object pool. Any object pool is necessarily going to at least have synchronization issues tied to it which may in the end cost more overall than creating and disposing of the objects. Modern GCs are pretty good about tossing away temporary objects. Now, if you're perhaps doing some things in a tight loop, then maybe simply a judicious use of the objects would be better. Say, rather than using a generic object pool, simply creating the few necessary instances for your loop before hand and reusing them explicity within the loop rather than constantly creating new ones. Regards, Will Hartung ([EMAIL PROTECTED]) - Original Message - From: Felipe Schnack [EMAIL PROTECTED] To: Tomcat Users List [EMAIL PROTECTED] Sent: Friday, December 20, 2002 11:00 AM Subject: object pooling Maybe I should be posting this on a commons maillist or something? Well, the problem is that I have some objects that I'm instantiaing tons of times in my application, and so, I would like to pool them. There is somewhere a good dummies guide to commons-pool jar? The javadocs aren't enough :-) -- Felipe Schnack Analista de Sistemas [EMAIL PROTECTED] Cel.: (51)91287530 Linux Counter #281893 Centro Universitário Ritter dos Reis http://www.ritterdosreis.br [EMAIL PROTECTED] Fone/Fax.: (51)32303341 -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: Tag object pooling and immutability in the servlet spec
Craig R. McClanahan [EMAIL PROTECTED] wrote in message news:20021027171704.R78647-10;icarus.apache.org... On Sat, 26 Oct 2002, Bill Barker wrote: Date: Sat, 26 Oct 2002 23:57:55 -0700 From: Bill Barker [EMAIL PROTECTED] Reply-To: Tomcat Users List [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Re: Tag object pooling and immutability in the servlet spec Craig R. McClanahan [EMAIL PROTECTED] wrote in message news:20021025095901.K36250-10;icarus.apache.org... On 24 Oct 2002, Mr. Tomcat wrote: Date: 24 Oct 2002 17:37:36 -1000 From: Mr. Tomcat [EMAIL PROTECTED] Reply-To: Tomcat Users List [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Tag object pooling and immutability in the servlet spec Is there a way to turn off tag object pooling? Object pooling was a cool performance technique in earlier versions of Java, but now object creation is very fast, so it no longer serves a performance function, and it introduces extra complexity into tag object design. Is this misfeature going to be phased out? No. Your assumption that it no longer serves a performance function is not correct. Just as an example of why it still matters, consider something like this (using the JSTL iteration tag): c:forEach var=i begin=0 end=999 mytags:foo index=${i} .../ /c:forEach The tag reuse mechanisms allow a page compiler to create one instance of the mytags:foo. tag and reuse it for every iteration through the loop, instead of creating 1000 of them. No matter how cheap object creation gets, there is still a difference -- and that difference is still significant on webapps with large numbers of users. While I haven't tracked it down completely, this is my favorite bug-bear for the 4.1.x (lack of) performance wrt JSPs. What Craig isn't telling you is that 4.1.x will issue 2000 calls to synchronized methods to allocate/release the tags in the above example. That's got to hurt :). I tried to very precise in my wording, but obviously didn't succeed at making an important point. The JSP specification's description of tag lifecycle (i.e. the ability to allocate an instance and then use it multiple times before releasing it) makes the optimization I described *possible* -- that has nothing to do with whether a particular implementation of the page compiler actually implements it. And, AFAIK, Jaser2 does not (yet) implement this feature. When this optimization is actually implemented, there will be *one* allocation and *one* release of the instance for the mytags:foo tag in the loop above, whether or not tag instance pooling is actually used. One of the primary goals of creating Jasper2 was to make it possible to implement optimizations like this, by having the page compiler retain sufficient information about the parse tree to implement things like this (which optimizing compilers have been doing to programming languages for a couple of decades now). With Jasper1, it was basically not feasible, because the page compiler retained essentially no state information about the source code of the page. Sorry, I was just venting. :( Once I've managed to squash a Jk2 bug (I sure don't want to compare the 3.3.1 standalone to the 4.1.13 standalone :), I'll have a place to start on contributing to Jasper2 (and, really, you've known me long enough to know that :). Craig -- To unsubscribe, e-mail: mailto:tomcat-user-unsubscribe;jakarta.apache.org For additional commands, e-mail: mailto:tomcat-user-help;jakarta.apache.org
Re: Tag object pooling and immutability in the servlet spec
Craig R. McClanahan [EMAIL PROTECTED] wrote in message news:20021025095901.K36250-10;icarus.apache.org... On 24 Oct 2002, Mr. Tomcat wrote: Date: 24 Oct 2002 17:37:36 -1000 From: Mr. Tomcat [EMAIL PROTECTED] Reply-To: Tomcat Users List [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Tag object pooling and immutability in the servlet spec Is there a way to turn off tag object pooling? Object pooling was a cool performance technique in earlier versions of Java, but now object creation is very fast, so it no longer serves a performance function, and it introduces extra complexity into tag object design. Is this misfeature going to be phased out? No. Your assumption that it no longer serves a performance function is not correct. Just as an example of why it still matters, consider something like this (using the JSTL iteration tag): c:forEach var=i begin=0 end=999 mytags:foo index=${i} .../ /c:forEach The tag reuse mechanisms allow a page compiler to create one instance of the mytags:foo. tag and reuse it for every iteration through the loop, instead of creating 1000 of them. No matter how cheap object creation gets, there is still a difference -- and that difference is still significant on webapps with large numbers of users. While I haven't tracked it down completely, this is my favorite bug-bear for the 4.1.x (lack of) performance wrt JSPs. What Craig isn't telling you is that 4.1.x will issue 2000 calls to synchronized methods to allocate/release the tags in the above example. That's got to hurt :). Since, at the moment, there is no (practical) way to disable tag-pooling, I'll have to wait until I disable it in the build to know for sure if this is why it is so slow. If tag reuse really makes your tags more complex, you're probably designing them wrong (and I'm talking to myself as well; I've been guilty of that particular mistake). Also, on the immutable object topic, it seems that it would be better to have all the initialization of servlets and filters done in the constructor, not by calling an init function. If everything could be set in the constructor, then all instance fields could be private final, meaning that the servlet or filter object could be immutable, and therefore known to be threadsafe, which is an issue with servlets. Any chance of these changes happening in future releases of the servlet spec? The constructor of a Servlet (or Filter) doesn't have access to the ServletConfig (or FilterConfig) object, so it cannot acquire initialization parameters, a reference to the ServletContext instance, or anything like that. Because javax.servlet.Servlet and javax.servlet.Filter are interfaces (not classes), you can't declare constructors in them. Therefore, the servlet spec requires that there be a zero-args constructor available so that instances can be dynamically instantiated. Would it be possible to require servlets and filters to have a constructor that takes a ServletConfig (or FilterConfig) argument? Sure ... at the cost of breaking every Servlet or Filter that has ever been written. Doesn't seem like a smart idea to implement something that is purely cosmetic, and wouldn't change the actual functionality provided by the container. There's much more important things for the spec to address. Thanks Craig McClanahan -- To unsubscribe, e-mail: mailto:tomcat-user-unsubscribe;jakarta.apache.org For additional commands, e-mail: mailto:tomcat-user-help;jakarta.apache.org
Re: Tag object pooling and immutability in the servlet spec
On Sat, 26 Oct 2002, Bill Barker wrote: Date: Sat, 26 Oct 2002 23:57:55 -0700 From: Bill Barker [EMAIL PROTECTED] Reply-To: Tomcat Users List [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Re: Tag object pooling and immutability in the servlet spec Craig R. McClanahan [EMAIL PROTECTED] wrote in message news:20021025095901.K36250-10;icarus.apache.org... On 24 Oct 2002, Mr. Tomcat wrote: Date: 24 Oct 2002 17:37:36 -1000 From: Mr. Tomcat [EMAIL PROTECTED] Reply-To: Tomcat Users List [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Tag object pooling and immutability in the servlet spec Is there a way to turn off tag object pooling? Object pooling was a cool performance technique in earlier versions of Java, but now object creation is very fast, so it no longer serves a performance function, and it introduces extra complexity into tag object design. Is this misfeature going to be phased out? No. Your assumption that it no longer serves a performance function is not correct. Just as an example of why it still matters, consider something like this (using the JSTL iteration tag): c:forEach var=i begin=0 end=999 mytags:foo index=${i} .../ /c:forEach The tag reuse mechanisms allow a page compiler to create one instance of the mytags:foo. tag and reuse it for every iteration through the loop, instead of creating 1000 of them. No matter how cheap object creation gets, there is still a difference -- and that difference is still significant on webapps with large numbers of users. While I haven't tracked it down completely, this is my favorite bug-bear for the 4.1.x (lack of) performance wrt JSPs. What Craig isn't telling you is that 4.1.x will issue 2000 calls to synchronized methods to allocate/release the tags in the above example. That's got to hurt :). I tried to very precise in my wording, but obviously didn't succeed at making an important point. The JSP specification's description of tag lifecycle (i.e. the ability to allocate an instance and then use it multiple times before releasing it) makes the optimization I described *possible* -- that has nothing to do with whether a particular implementation of the page compiler actually implements it. And, AFAIK, Jaser2 does not (yet) implement this feature. When this optimization is actually implemented, there will be *one* allocation and *one* release of the instance for the mytags:foo tag in the loop above, whether or not tag instance pooling is actually used. One of the primary goals of creating Jasper2 was to make it possible to implement optimizations like this, by having the page compiler retain sufficient information about the parse tree to implement things like this (which optimizing compilers have been doing to programming languages for a couple of decades now). With Jasper1, it was basically not feasible, because the page compiler retained essentially no state information about the source code of the page. Craig -- To unsubscribe, e-mail: mailto:tomcat-user-unsubscribe;jakarta.apache.org For additional commands, e-mail: mailto:tomcat-user-help;jakarta.apache.org
Re: Tag object pooling and immutability in the servlet spec
Mr. Tomcat wrote: Is there a way to turn off tag object pooling? Object pooling was a cool performance technique in earlier versions of Java, but now object creation is very fast, so it no longer serves a performance function, and it introduces extra complexity into tag object design. Is this misfeature going to be phased out? In more recent JVM's object creation is faster, but those objects also need to be garbage collected later. Large numbers of objects requiring GC can significantly degrade performance. The above statement is a generalization that doesn't apply in all cases. In Jasper 2 custom JSP tag pooling provides a huge boost in performance for JSP pages which use custom tags. Request latency for JSP pages which use custom tags was reduced significantly and the system can now scale to handle larger numbers of concurrent requests. Before upgrading to Jasper 2 we had upgraded the hardware from single to dual cpu's and tripled the system ram. We still had some scaling problems. Upgrading to Jasper 2 a few weeks later solved are problems. It improved performance as much or more than the hardware upgrade. (The site uses alot of JSP pages with custom tags). This is on Sun sparc's running Solaris with JDK 1.3.1. I'll let someone else address your other issue. Regards, Glenn Also, on the immutable object topic, it seems that it would be better to have all the initialization of servlets and filters done in the constructor, not by calling an init function. If everything could be set in the constructor, then all instance fields could be private final, meaning that the servlet or filter object could be immutable, and therefore known to be threadsafe, which is an issue with servlets. Any chance of these changes happening in future releases of the servlet spec? Thanks -- To unsubscribe, e-mail: mailto:tomcat-user-unsubscribe;jakarta.apache.org For additional commands, e-mail: mailto:tomcat-user-help;jakarta.apache.org -- To unsubscribe, e-mail: mailto:tomcat-user-unsubscribe;jakarta.apache.org For additional commands, e-mail: mailto:tomcat-user-help;jakarta.apache.org
Re: Tag object pooling and immutability in the servlet spec
On 24 Oct 2002, Mr. Tomcat wrote: Date: 24 Oct 2002 17:37:36 -1000 From: Mr. Tomcat [EMAIL PROTECTED] Reply-To: Tomcat Users List [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Tag object pooling and immutability in the servlet spec Is there a way to turn off tag object pooling? Object pooling was a cool performance technique in earlier versions of Java, but now object creation is very fast, so it no longer serves a performance function, and it introduces extra complexity into tag object design. Is this misfeature going to be phased out? No. Your assumption that it no longer serves a performance function is not correct. Just as an example of why it still matters, consider something like this (using the JSTL iteration tag): c:forEach var=i begin=0 end=999 mytags:foo index=${i} .../ /c:forEach The tag reuse mechanisms allow a page compiler to create one instance of the mytags:foo. tag and reuse it for every iteration through the loop, instead of creating 1000 of them. No matter how cheap object creation gets, there is still a difference -- and that difference is still significant on webapps with large numbers of users. If tag reuse really makes your tags more complex, you're probably designing them wrong (and I'm talking to myself as well; I've been guilty of that particular mistake). Also, on the immutable object topic, it seems that it would be better to have all the initialization of servlets and filters done in the constructor, not by calling an init function. If everything could be set in the constructor, then all instance fields could be private final, meaning that the servlet or filter object could be immutable, and therefore known to be threadsafe, which is an issue with servlets. Any chance of these changes happening in future releases of the servlet spec? The constructor of a Servlet (or Filter) doesn't have access to the ServletConfig (or FilterConfig) object, so it cannot acquire initialization parameters, a reference to the ServletContext instance, or anything like that. Because javax.servlet.Servlet and javax.servlet.Filter are interfaces (not classes), you can't declare constructors in them. Therefore, the servlet spec requires that there be a zero-args constructor available so that instances can be dynamically instantiated. Would it be possible to require servlets and filters to have a constructor that takes a ServletConfig (or FilterConfig) argument? Sure ... at the cost of breaking every Servlet or Filter that has ever been written. Doesn't seem like a smart idea to implement something that is purely cosmetic, and wouldn't change the actual functionality provided by the container. There's much more important things for the spec to address. Thanks Craig McClanahan -- To unsubscribe, e-mail: mailto:tomcat-user-unsubscribe;jakarta.apache.org For additional commands, e-mail: mailto:tomcat-user-help;jakarta.apache.org
Tag object pooling and immutability in the servlet spec
Is there a way to turn off tag object pooling? Object pooling was a cool performance technique in earlier versions of Java, but now object creation is very fast, so it no longer serves a performance function, and it introduces extra complexity into tag object design. Is this misfeature going to be phased out? Also, on the immutable object topic, it seems that it would be better to have all the initialization of servlets and filters done in the constructor, not by calling an init function. If everything could be set in the constructor, then all instance fields could be private final, meaning that the servlet or filter object could be immutable, and therefore known to be threadsafe, which is an issue with servlets. Any chance of these changes happening in future releases of the servlet spec? Thanks -- To unsubscribe, e-mail: mailto:tomcat-user-unsubscribe;jakarta.apache.org For additional commands, e-mail: mailto:tomcat-user-help;jakarta.apache.org
RE: Object pooling
You might post this on [EMAIL PROTECTED] instead - Andrew -Original Message- From: John Walstra [mailto:[EMAIL PROTECTED]] Sent: Thursday, September 05, 2002 1:23 AM To: Tomcat Mailing List Subject: Object pooling Hi ya, I'm trying to pool some objects. The objects consist of a hash filled in from XML files. I don't really want to reload the objects for each page hit and it's used by an object that can't be scoped for the application. I've grabbed commons-pool and incorporated it into my code. I have no errors, but my debug messages indicate that it's not grabbing the object from the pool, but is reloading them each time. I've concluded that I've I'm not using commons-pool correct with Tomcat. Do I need to set it up as a resource? Documentation is kind of spare right now. Thanks, John -- John Walstra [EMAIL PROTECTED] The world is no nursery. - Sigmund Freud -- To unsubscribe, e-mail: mailto:tomcat-user- [EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED] -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Object pooling
Hi ya, I'm trying to pool some objects. The objects consist of a hash filled in from XML files. I don't really want to reload the objects for each page hit and it's used by an object that can't be scoped for the application. I've grabbed commons-pool and incorporated it into my code. I have no errors, but my debug messages indicate that it's not grabbing the object from the pool, but is reloading them each time. I've concluded that I've I'm not using commons-pool correct with Tomcat. Do I need to set it up as a resource? Documentation is kind of spare right now. Thanks, John -- John Walstra [EMAIL PROTECTED] The world is no nursery. - Sigmund Freud -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]