An interesting point. I get the part about "stupid webapps" (e.g. loading a configuration file once and never checking it again), but I find the PermGen part surprising. Would you care to provide more detail? I thought that PermGen was garbage collected in modern JVMs; furthermore, wouldn't the new version of the application still use (roughly) the same classes/methods and thus (roughly) the same space?
This happens because Tomcat is unable to release some classes from the classloader. So every time I load a new WAR lets say I am using Spring. Tomcat doesn't remove the old Spring Jar from the classloader and just loads a second one for my updated WAR. After doing this a few times (Depending on the size of your app, permgen size and how many 3rd party libraries you have) tomcat will throw a permgen error. There is nothing Tomcat can do about this. It is the classloaders problem. Also it is not recommended to "hot deploy" to a production environment.
I've done some more reading on this issue, and I don't think what you are saying is correct.
First, class loading is more granular than JAR files. From what I can tell, the JARs are just repositories (if you will) for the actual class data. Once a class has been loaded from a JAR, it is distinct from it, and there is no need to keep the whole JAR in memory.
Second, there are many class loaders at play, not just one. At the least, there will be one class loader for Tomcat and one class loader for each web app. This is necessary to keep web apps from breaking each other (and Tomcat!) by loading incompatible versions of classes.
Third, once a class is no longer used (i.e. there exist no objects that are instances of it) it can be garbage collected, and will be if more PermGen space is needed.
Fourth, once a web app is unloaded, its class loader is no longer needed, and it too can be garbage collected (along with any memory it was using to store the aforementioned JAR files, although presumably that memory would be outside of PermGen).
Taking all of this into account, one might (like me) naively presume that once you unload a web app, all of its objects will no longer be referenced, and this will propagate up the tree of references (servlet -> object -> ... -> object -> class) until nothing from that app remains.
HOWEVER, this assumes that references exist in a tree. A singleton class would cause problems: it stores a reference to an object of its own type. This creates a circular reference pattern (class X -> object -> class X) and keeps both class and object in memory.
A possible solution might be to associate each class with the web app that loaded it, then when you unload a web app, you can walk through all of the classes it loaded and null out all of their static fields. This will allow the referenced objects to be garbage collected, and in turn, the classes of those objects.
But this is probably much easier said than done (it may even be impossible due to limitations on the JVM), and there are probably other issues I'm not even aware of and thus not considering. Never mind JNI, which just adds even more fun to the mix.
So ultimately I must agree with the recommendation to restart Tomcat when you're deploying web apps. From a developer perspective, I would also recommend eliminating static data in your libraries and web apps as much as possible.