The other thing is: Cygwin users, it's time to stop using that damn DOS box!
The trick is:
The above is a rough paraphrase of something Lui, my advisor and mentor in grad school, used to say reguarly. Lui is a damn smart guy, and that has really stuck with me over the years. If you try and solve the general problem of finding things like JDBC leaks, EJB leaks or any other technically "intractable" problem, you're just gonna end up stuck in the weeds digging for years with no answer. I'm certainly not smart enough to solve the halting problem, and my guess is you're not either.
What you can, instead, do is look for the pattern of how you fetch and release database connections in your system, using your frameworks and code standards. If something doesn't match the pattern, it's probably a leak, but if nothing else, it's definitely something odd that doesn't match the rest of the system and should be looked at.
I built an EJB leak checker for the system I'm currently building that scans for things that don't match how we fetch and release EJBs. Thus far, it's found something like 99.9% of all of our leaks, if not 100% (damn halting problem.. I can't tell!). Certainly the before and after of runninging it shows a much more reliable application afterwards under load. It works so well we integrated it into the build, and the build halts if there's a probable leak. If you can do this for your system, I fully encourage it. It saves on JProbe licenses :-)
The general principal is pretty simple. I included the corollary just because I needed to write it down. From an ergonomics perspective, causing yourself pain can happen a myriad of ways. The way I'm currently fighting this is how to deal with correct monitor position on multidisplay machines. If you have it wrong, you cause yourself neck, shoulder and back pain as you twist your body in funny ways to look at things that are at some weird angle to your body and normal position. If this gets bad enough (and, yes, like everything else, I took this to a pretty distant extreme) you'll really fuck your body up.
So: If you start to hurt, see a doctor. And start moving around your monitor, chair, etc, to fix it. Don't let it go on, or you'll regret it later.
Under lab conditions where you have fast clients and very low network latency, having each client consume a thread on the server is totally fine, because the time to send the response to the client is negligable. This allows threads to quickly recycle after they finish their work cycle.
The problem is, this is actually the best case scenario. Under real-world workloads, where clients are slow and packet loss is rampant, what ends up happening is your server bogs down trying to send data to slow clients. So if one client is on a 56K modem and everyone else is on a T1, that 56K modem will actually consume a thread and impact performance for all the rest of the users on the appserver. The thread that sends the slow client event static content will stay stuck and unable to do useful work until the download completes. This has a very real impact on the server as a whole, because the thread pool will quickly exhaust and people will queue and wait for threads that can service them.
Originally, before I figured out what was going on, I was boosting the thread pool size on the server to rediculous levels (well over 150) just based on trial and error results from remote load testing across the internet. I had discovered that the higher the thread pool numbers, the faster things seemed to be for people. However, huge thread counts start causing the operating system problems, primarily in scheduler overhead trying to properly do the run queue.
This is where mod_proxy comes in. This apache module is written in C, has internal response buffers and is intended to deal with tons of slow clients without eating tons of critical OS resources, like threads (which, unfortunately, is not possible before JDK 1.4). If you put it in front of your application, suddenly, when the threads complete their work cycles, they return the data to the proxy and immediately are ready for service again. The throughput of your server suddenly skyrockets because the java side of things is actually spending time doing useful work, rather than buffering data to slow clients.
And, just for your boot notes, the Apache mod_weblogic that comes with the appserver does not release the appserver-side resources until the actual client completes. This is just based on observation of server operation and not empirical testing, and should be further verified, but there is STRONG evidence that mod_proxy makes much more efficient use of your appserver resources.
From the Apache mod_proxy documentation (thanks Igor): When a response is received which fits entirely within the IO buffer size, the remote HTTP or FTP server socket will be closed before an attempt is made to write the response to the client. This ensures that the remote server does not remain connected unnecessarily while the response is delivered to a slow client. A high value for the IO buffer decreases the load on remote HTTP and FTP servers, at the expense of greater RAM footprint on the proxy So long story short is: make your I/O buffers LARGE in your mod_proxy to take the heat off your appserver. Reference for mod_proxy here
Normally, to add or modify an EJB, you have to update 4 files: The Remote interface, the Bean implementation, and potentially the ejb-jar.xml and weblogic-ejb-jar.xml files. To create an EJB, you also have to make a Home interface. All of this is really quite useless from a productivity point of view. I've been through several revisions of code generators to try and solve this problem, and none of them really worked ALL that well. You may cut the 4 file edits down to 2, but 2 is still too many, and causes a huge pain when things get out of sync. This leads to your ejb code being a total mess.
Enter XDoclet: The correct approach. This is a code generator that is driven not from an external document, but from actual annotations in the sources. This lets you edit (or create) one file for your ejbs, and the system handles the rest. Combine this with an IntelliJ macro, and suddenly the business of making EJBs changes dramatically.
Other useful blogs I like to read:
misbehaving
boingboing
k5
/dev/null
crazy bob
igor's lampost
vanity foul
James Strachan's Radio Weblog
Otaku