Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I cannot for the life of me find a definition of what the Java VM flag
CMSClassUnloadingEnabled
actually does, other than some very fuzzy high-level definitions such as "gets rid of your PermGen problems" (
which it doesn't
, btw).
I have looked on Sun's/Oracle's site, and even
the options list
doesn't actually say what it does.
Based upon the name of the flag, I'm guessing that the CMS Garbage Collector doesn't by default unload classes, and this flag turns it on - but I can't be sure.
Update
This answer is relevant for Java 5-7, Java 8 has this fixed:
https://blogs.oracle.com/poonam/about-g1-garbage-collector,-permanent-generation-and-metaspace
Kudos go to
mt.uulu
For Java 5-7:
The standard Oracle/Sun VM look on the world is: Classes are forever. So once loaded, they stay in memory even if no one cares anymore. This usually is no problem since you don't have that many purely "setup" classes (= used once for setup and then never again). So even if they take up 1MB, who cares.
But lately, we have languages like Groovy, that define classes at runtime. Every time you run a script, one (or more) new classes are created and they stay in PermGen forever. If you're running a server, that means you have a memory leak.
If you enable
CMSClassUnloadingEnabled
the GC will sweep PermGen, too, and remove classes which are no longer used.
[EDIT]
You will also have to enable
UseConcMarkSweepGC
(thanks to
Sam Hasler
). See this answer:
https://stackoverflow.com/a/3720052/2541
–
–
–
–
According to the blog post
The most complete list of -XX options for Java JVM
, it determines if class unloading is enabled under the CMS garbage collector. The default is
false
. There is another option called
ClassUnloading
that is
true
by default which (presumably) affects the other garbage collectors.
The idea is that if the GC detects that a previously loaded class is no longer used anywhere in the JVM, it can reclaim the memory used to hold the classes bytecode and/or native code.
Setting CMSClassUnloadingEnabled
might
help with your permgen problem
if you are currently using the CMS collector
. But the chances are that you are not using the CMS, or that you have a genuine classloader related memory leak. In the latter case, your class will never appear to the GC to be unused ... and will therefore never be unloaded.
Aaron Digulla says "classes are for ever". This is not strictly true, even in the purely Java world. In fact, the lifetime of a class is tied to its classloader. So if you can arrange that a classloader is garbage collected (and that is not always an easy thing to do) the classes that it loaded will also be garbage collected.
In fact, this is what happens when you do a hot redeploy of a webapp. (Or at least, that's what should happen, if you can avoid the problems that lead to a permgen storage leak.)
An example where this is useful:
Setting
-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled
on our Weblogic 10.3 JVM helped resolving a problem where the JAX-WS implementation created a new proxy class for every web service call, eventually leading to out of memory errors.
It wasn't trivial to trace. The following code always returned the same proxy class for
port
final MyPortType port =
Service.create(
getClass().getResource("/path/to.wsdl"),
new QName("http://www.example.com", "MyService"))
.getPort(
new QName("http://www.example.com", "MyPortType"),
MyPortType.class);
Internally, this proxy delegated to an instance of weblogic.wsee.jaxws.spi.ClientInstance
, which again delegated to a new $Proxy[nnnn]
class where n
was incremented at every call. When adding the flags, n
was still incremented, but at least those temporary classes were removed from memory.
On a more general note, this can be very useful when making heavy use of Java reflection and proxies through java.lang.reflect.Proxy
–
–
–
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.