Possible Memory leak in Number of Loaded classes in Java Application

I recently began profiling an osgi java application that I am writing using VisualVM. One thing I have noticed is that when the application starts sending data to a client (over JMS), the number of loaded classes starts increasing at a steady rate. The Heap size and the PermGen size remains constant, however. The number of classes never falls, even after it stops sending data. Is this a memory leak? I think it is, because the loaded classes have to be stored somewhere, however the heap and permgen never increase even after I run the application for several hours.

For the screenshot of my profiling application go here


Are you dynamically creating new classes on the fly somehow?

Thanks for your help. I figured out what the problem is. In one of my classes, I was using Jaxb to create an XML string. In doing this, JAXB ueses reflection to create a new class.

JAXBContext context = JAXBContext.newInstance(this.getClass());

So although the JAXBContext wasn't saying around in the heap, the classes had been loaded.

I have run my program again, and I see a normal plateau as I would expect.


I'm willing to bet that your problem is related to bytecode generation.

Many libraries use CGLib, BCEL, Javasist or Janino to generate bytecode for new classes at runtime and then load them from controlled classloader. The only way to release these classes is to release all references to the classloader.

Since the classloader is held by each class, this also means that you should not release the references to all classes as well [1]. You can catch these with a decent profiler (I use Yourkit - search for multiple classloader instances with the same retained size)

One catch is that the JVM does not unload classes by default (the reason is backwards compatibility - that people assume (wrongly) that static initializers would be executed only once. The truth is that they get executed every time a class is loaded.) To enable unloading, you should pass some use the following options:

-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled

(tested with JDK 1.5)

Even then, excessive bytecode generation is not a good idea, so I suggest you look in your code to find the culprit and cache the generated classes. Frequent offenders are scripting languages, dynamic proxies (including the ones generated by application servers) or huge Hibernate model (in this case you can just increase your permgen).

See also:

  • http://blogs.oracle.com/watt/resource/jvm-options-list.html
  • http://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation
  • http://forums.sun.com/thread.jspa?messageID=2833028

  • You might find some hotspot flags to be of use in understanding this behavior like:

  • -XX:+TraceClassLoading
  • -XX:+TraceClassUnloading
  • This is a good reference:

    http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp

    链接地址: http://www.djcxy.com/p/19836.html

    上一篇: 为什么Java堆的最大大小是固定的?

    下一篇: Java应用程序中已加载类的数量可能会发生内存泄漏