182 votes

Que fait réellement le flag JVM CMSClassUnloadingEnabled?

Je ne peux pas pour la vie de me trouver une définition de ce que la machine virtuelle Java drapeau CMSClassUnloadingEnabled ne fait, à part quelques très floue de haut niveau des définitions telles que "se débarrasser de votre PermGen problèmes" (dont il n'a pas, d'ailleurs).

J'ai regardé sur de Sun/Oracle du site, et même la liste des options n'est pas réellement dire ce qu'il fait.

Basé sur le nom de l'indicateur, je devine que le CMS Garbage Collector n'est pas par défaut décharger les classes, et cet indicateur s'allume mais je ne peux pas en être sûr.

215voto

Aaron Digulla Points 143830

Le standard d'Oracle/Sun VM regard sur le monde: les Classes sont toujours. Donc, une fois chargé, ils restent en mémoire, même si personne ne s'en soucie plus. Généralement, ceci n'est pas un problème puisque vous n'avez pas que beaucoup de purement "setup" classes (= utilisé une fois pour l'installation et jamais encore). Donc, même si ils prennent à 1 mo, qui s'en soucie.

Mais dernièrement, nous avons des langues comme Groovy, qui définissent les classes au moment de l'exécution. Chaque fois que vous exécutez un script, un (ou plusieurs) de nouvelles classes sont créées et qu'ils restent dans PermGen pour toujours. Si vous utilisez un serveur, cela signifie que vous avez une fuite de mémoire.

Si vous activez CMSClassUnloadingEnabled le GC balayage PermGen, trop, et supprimer les classes qui ne sont plus utilisés.

[EDIT] Vous devrez également activer UseConcMarkSweepGC (merci à Sam Hasler). Voir cette réponse: http://stackoverflow.com/a/3720052/2541

35voto

Stephen C Points 255558

Selon ce lien, il détermine si la classe de déchargement est permis en vertu de la CMS garbage collector. La valeur par défaut est false. Il y a une autre option appelée" ClassUnloading c'est - true par défaut, ce qui (sans doute) affecte les autres ramasseurs d'ordures.

L'idée est que si le GC détecte que précédemment chargés de classe n'est plus utilisé n'importe où dans la JVM, il peut récupérer de la mémoire utilisée pour tenir le bytecode des classes et/ou en code natif.

Réglage CMSClassUnloadingEnabled peut aider avec votre permgen problème si vous utilisez actuellement le CMS collector. Mais les chances sont que vous n'êtes pas en utilisant le CMS, ou que vous avez un vrai chargeur de classe de la mémoire liée à la fuite. Dans ce dernier cas, votre classe n'apparaît jamais à la GC inutilisés ... et ne sera donc jamais être déchargé.


Aaron Digulla dit "les classes sont à jamais". Ce n'est pas strictement vrai, même dans le purement monde Java. En fait, la durée de vie d'une classe est liée à son chargeur de classe. Donc, si vous pouvez organiser un chargeur de classe est le garbage collector (et qui n'est pas toujours une chose facile à faire) les classes qu'elle chargés seront également ordures collectées.

En fait, c'est ce qui se passe quand vous faites une chaude redéployer d'une webapp. (Ou au moins, c'est ce qui devrait arriver, si vous pouvez éviter les problèmes qui mènent à un permgen de stockage de fuite.)

24voto

Lukas Eder Points 48046

Un exemple où cela est utile:

Paramètre -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled sur notre Weblogic 10.3 JVM contribué à la résolution d'un problème où le JAX-WS mise en œuvre créé une nouvelle classe de proxy pour chaque appel de service web, pour aboutir finalement à des erreurs de mémoire insuffisante.

Il n'était pas trivial de trace. Le code suivant retourne toujours la même classe proxy pour 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);

En interne, cette procuration, déléguée à une instance d' weblogic.wsee.jaxws.spi.ClientInstance, qui est de nouveau confiée à un nouveau $Proxy[nnnn] classe où l' n a été incrémenté à chaque appel. Lors de l'ajout des drapeaux, n a été incrémentée, mais au moins ces classes temporaires ont été supprimées de la mémoire.

Sur un plan plus général, cela peut être très utile lors de l'utilisation lourde de la réflexion Java et mandataires à travers java.lang.reflect.Proxy

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X