You wrote: >The CM's lookup/release pair remind me a lot of the new/delete pair >-- >which we don't have in Java because the VM does the 'delete' for us. > >If it is ok to let the VM reclaim memory assigned to objects without >having much control over the process, why is there a problem applying >this approach to reclaiming components for a pool? > >couldn't the same arguments work in each case?
Robert, the arguments are not the same. You equate a component with something like a String instance - an object that is cheap and doesn't cause any harm by being on the heap. For example, the code: for (int i = 0; i < 1000; i++) { String s = new String ("This is String number " + i); } eats up some heap space, but that is all. The rest of the system is not adversely affected by the String instances on the heap, as we have not "used up" 1000 precious String instances. To put it another way, there is no shortage of Strings - use as many as you want! However, this code: for (int i = 0; i < 1000; i++) { InputStream is = new FileInputStream ("some_file." + i); } is more dangerous. As we open files without closing them, the file handles will remain open until the InputStreams are GC:ed. This is bad, because as long as those InputStreams are on the heap, they hold on to a limited system resource - file handles. There is no shortage of Strings, but there is a shortage of file handles. That's why you should call close() on all streams that you open, instead of waiting for them to be GC:ed. There are other examples of "precious" objects - for example DB connections. PostgreSQL allows (by default) only a maximum of 24 simultaneous connections. That's why you should call close() on your DB connections as soon as possible. (Even though other DBs may have other defaults.) I hope the above explains why I do not think GC of components can be considered equivalent to GC of regular objects. "But", you say, "all components that are "rare" and thus must be close()'d or similar, they usually have a close() method, so why bother at all? It appears that all objects that needs something besides normal GC already have the extra mechanisms they need." The problem with that is that in Avalon, you do not know if the component you are using needs something besides the usual GC. Every component is defined by its interface, but the actual implementation may vary. So you may have an implementation that works fine with normal GC, and one that needs to be explicitly close()'d or equivalent. As the interface must be able to accomodate both, you end up writing the interface for worst-case: you include a close() method (or something else equivalent). Consider, for example, that you could switch implementations of InputStream to one that does not need you to call close(). Let's say this may or may not be supported on your target system. So we have a FileInputStream whose close() method is empty (for backwards compatibility). Right, what do you code? Well, since you do not know if your code will run on a system with no-need-to-close- streams, you end up writing code to close the stream anyway. The same reasoning is behind my wish for a release() mechanism. Since we do not know whether the component is pooled or not, and since no suitable automatic method of reclaiming components have been found (and I doubt it will be found in time for Avalon 6 even), we must have a release() mechanism. > If the only reason for using pools is performance then some tuning is > to be expected whenever they are used (e.g. determining the pool > size). This tuning is going to be dependent on implementation (e.g. > different implementations will require different pool sizes for best > performance). The GC settings are: 1) *Brutally* difficult to tune. I do not even know if it is possible. 2) Global. Tune one pool, tune all. This makes it difficult to find values that work. Set value A too high, and your DB connection pool is suffering, set it lower and some other pool starts acting up. > finally, if a pool runs out of components there is nothing stopping it > from running the garbage collector itself [though again, this would > need tuning -- but might make reduce the differences between VMs]. Actually, there is. How do you run the collector? The System.gc() call is only a *suggestion* to the VM to collect. Calling it does not guarantee GC at all. And even if you do run GC, there is no guarantee that *all* unreachable objects are finalized - for various reasons, the VM may leave some for the next pass. Which may not happen in a while. I hope this explains my reasoning behind my opposition to the GC-as-component- release line, and my strong pro-release() stance. /LS -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>