13

ClassLoader leaks usually result in java.lang.OutOfMemoryError: PermGen. In the instance of working on application servers you may see this as a result of many redeploys of a common application. The explanation and possible resolutions to this problem can be seen on these two links. (among others)

http://blogs.oracle.com/fkieviet/entry/classloader_leaks_the_dreaded_java http://dev.eclipse.org/blogs/memoryanalyzer/2008/05/17/the-unknown-generation-perm/

Now for the most part they are easy to get around. Simply increase the -XX:MaxPermSize and when the inevitable happens, restart the JVM completely. The problem with trying to solve this is that in large applications many classes can cause the classloader to leak and thus the classes to stay within the permgen.

Two questions arise from this:

Is it reasonable to say that an issue like this is better to just increase the max perm size and restart where necessary or should finding a resolution be a higher priority?

Are there easier ways to resolve a classloader leak?

Emil Sierżęga
  • 1,785
  • 2
  • 31
  • 38
John Vint
  • 39,695
  • 7
  • 78
  • 108
  • btw, unrelated but leaks and java.util.Logger was one of the worst decisions coming in java 6.0.18.. that made 'em held by WeakReferences totally breaking a lot of existing code. – bestsss Jan 19 '11 at 23:51
  • Interesting question... it appears to me though that a class loader leak is always the result of different leak somewhere else in the system (e.g. an unwanted instance is hanging around therefore its class loader can't be collected, etc, etc...) Is this a fair conclusion? – CurtainDog Jan 20 '11 at 00:13
  • @CurtainDog Yes. The classloader will only leak if a class it loads is restricting it from being garbage collected. As the articles goes over, a servlet class that creates an anonymous inner class of one of bootstrap classes will cause the classloader to not get garbage collected – John Vint Jan 20 '11 at 00:19
  • no, it's not... absolutely innocently looking threads can leak classloaders as well, if you are not careful. – bestsss Jan 20 '11 at 00:22
  • @bestsss - thats a good point I was a bit too empirical there. – John Vint Jan 20 '11 at 00:25

5 Answers5

10

It really depends on the application, or rather, the deployment process being used. Many applications are only ever redeplyoed during development, new releases happen once every few months, and the application server is restarted for other reasons far more often than the app is deployed. In those circumstances, chasing Classloader leaks is a waste of time.

Of course, if you plan on implementing a continuous deployment process, especially in a high-availability environment, then Classloader leaks are something you really need to tackle. But there are a lot of other things you need to do better than most projects before that becomes an issue.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • This has pretty much been my stance since we observed the fact of the leak. Fortunately for this situation the former of your two situations is what I am dealing with so I can probably make an argument against not resolving it for the time being. – John Vint Jan 20 '11 at 14:18
  • leaks are easy to stop actually: jmap histogram and if you see 2 times exactly the same class, you know it's leaking. Leaks can become a serious problem if for some reason any class holds static references (but not ThreadLocal) to large structures like cache, ByteBuffers, etc... – bestsss Jan 20 '11 at 19:34
  • @bestsss: that's how you confirm that you *have* a leak. Actually fixing it can be arbitrarily more difficult. – Michael Borgwardt Jan 21 '11 at 08:55
  • opps I see where you are coming from stop=spot. a typo. didn't mean fixing at all. – bestsss Jan 21 '11 at 16:46
5

@biziclop is right. You need to be pragmatic about this.

If the problem is only in test servers, you can probably dismiss this as not worth the effort to solve.

If the problem is in production servers then you need a solution or a workaround. The solution is hard work, but the workarounds may be less work:

  • Workaround #1 - don't do hot deploys to production servers; only do full redeployments and restarts.

  • Workaround #2 - periodically do a full restart of the production servers to avoid running out of permgen space1. Combine this with increasing the permgen space.

In a well resourced / well run environment you should be doing all of your testing on separate servers. If the downtime of a full deployment is a concern, you should be minimizing redeployment disruptions using server replication and progressive redeployment. Hot deployments to production should be unnecessary.

If you are in the position where you have no test environment and are doing frequent hot deploys to a production machine to minimize downtime, you are skating thin ice. The chances are that you will eventually make a mistake that results in damage which takes a long time to recover from ...


1 - In Java 8 and later, permgen is gone. But the flipside is that a classloader leak will now leak memory in the regular heap.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
3

Yes, there are easier - and more proper - ways to resolve the leaks. Add the ClassLoader Leak Prevention library to your project, and it should take care of the problem for you!

In case you want to track down the leaks yourself, this blog series will be of help.

Mattias Jiderhamn
  • 2,053
  • 1
  • 13
  • 6
3

Those are one of the worst leaks... but any leak is evil. So, I, personally, resolve them. Profiling helps as well. There are no easy ways per se but:

  • Threads go into threadGroups +starter thread for each module to ensure new Threads() have that group.
  • Special care of the Thread.inheritedAccessControlContext (which holds a reference to the classloader)
  • WeakReferences when you need to keep classes, actually use WeakReferences for listeners, so no one can skip de-registers (and use only annon. clasess). Having the framework for WeakListeners does help.
  • Extra care for DB drives, java.security.Provider
  • few more tricks (incl. dynamic enhance of class files but that's overkill usually)

bottom line:


leaks are evil.

bestsss
  • 11,796
  • 3
  • 53
  • 63
2

I'd approach the problem pragmatically:

  1. Is it causing problems in production environments?
  2. Have you got enough time and resources to track it down?

If the answer to both these questions is yes, then by all means go for it. If it's one yes, one no, it's probably up to the management to decide, if both are nos, don't bother.

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • funny, i wont have my sleep at night if i know i am letting a class leak in the wild :) – bestsss Jan 19 '11 at 23:54
  • @bestsss It's called conscience, I think. Don't worry, it will go away after a few years. :) – biziclop Jan 20 '11 at 00:09
  • @ biziclop: i doubt... i am programming since i was 6 (and a half), it has been hell a lot of time and my conscience is still there. – bestsss Jan 20 '11 at 00:13
  • @bestsss What you need then is a treatment of weekly meetings about corporate values and quality management. Oh, and how to increase efficiency. – biziclop Jan 20 '11 at 00:21
  • @biziclop no one has complained about quality actually :P, as for efficiency I am quite a fast coder (still but the time takes its toll)... corporate stuff: well, whatever – bestsss Jan 20 '11 at 00:26
  • @bestss - your conscience should not come into it. It is sometimes necessary to compromise quality in order to get systems running within the constraints of the resources available to you. The boss says so ... and the boss understands the business better than you do. If you haven't been in this situation yet, you are lucky. – Stephen C Jan 20 '11 at 00:48
  • @Stephen C - i do understand the remark and also i am sorta lucky (last part) but i will also just fix the leak in my nights since i wont sleep (that was the point). by the time i wont be happy w/ the quality of the code i deliver i'd retire and do smth else... like being a bartender [everyone can dream, right?] – bestsss Jan 20 '11 at 00:51