Vous aimez ce que vous lisez sur ce blog ?
Envie d'aller plus loin avec véritable formation d'expertise en Java ?
Venez suivre ma formation Masterclasse Expertise Java !

"Même un développeur experimenté a besoin de continuer à apprendre. Et dans cette formation... j'ai appris beaucoup !" - A.G., Java Champion

Sessions intra-entreprises sur demande : contact[at]mokatech.net.
Inscrivez-vous vite !

Java Quiz #13

Une classe Java peut-elle être déchargée de la mémoire ?

Réponse : La réponse est oui, dixit la spécification du langage Java (chapitre 12.7), mais ce n'est pas obligatoire.

Ainsi, le gestionnaire de mémoire de la machine virtuelle de Sun, HotSpot, gère les classes (les instances de la classe Class, et toutes les autres données d'introspection) comme des objets. Son ramasse-miettes peut donc libérer la mémoire qu'une classe occupe lorsqu'elle n'est plus référencée, soit par une instance, soit par le code d'une autre classe. Au passage, cela permet de libérer aussi la mémoire occupée par tous les attributs statiques de la classe.

Les machines virtuelles BEA JRockit et IBM font de même. Les 3 JVM proposent d'ailleurs une option non standard -Xnoclassgc, qui permet de bloquer ce mécanisme.

Question subsidiaire : Comment bloquer à coup sûr le déchargement d'une classe, et s'assurer qu'elle existera jusqu'à ce que la JVM s'arrête ?

La solution la plus classique et la plus simple est de s'assurer qu'un bout de code, qui ne cessera de s'exécuter qu'à la fin du programme, garde une référence sur l'instance de la classe Class qui la désigne, ou sur un attribut statique de cette classe. On verra dans d'autres quizz qu'il existe aussi d'autres cas beaucoup plus tordus (et difficiles à détecter), qui s'apparentent plus à des fuites mémoire.


Commentaires

1. Le lundi 2 juin 2008, 16:56 par Histrion

Si je comprends bien ce que je lis sur le sujet, le classloader par défaut est celui de System. Et on ne peut décharger une classe qu'en même temps que son classloader. Du coup si tu charges une classe en mémoire "de manière classique", tu ne peux pas la décharger (ça reviendrait à vouloir décharger System...). Il faut charger la classe via son propre classloader (je lis que le code de TomCat est un bon HowTo).

Lien : http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ClassLoader.html

Je note "However, some classes may not originate from a file; they may originate from other sources, such as the network, or they could be constructed by an application." Est-ce que c'est de cette manière que Jython fonctionne ?

2. Le mardi 3 juin 2008, 10:51 par HollyDays

A priori, l'assertion «on ne peut décharger une classe qu'en même temps que son classloader» est fausse. Même s'il est probable que le classloader de bootstrap ait un fonctionnement particulier.

Je précise que le «classloader de bootstrap» (ou «classsloader primordial») n'est pas ce qu'on appelle le «classloader système» :

  • le classloader système est le classloader standard pour les classes des applications ;
  • le classloader de bootstrap est, quant à lui, responsable du chargement des classes du cœur de la JVM, du genre java.lang.System, java.lang.Runtime, java.lang.Thread, java.lang.Exception (et aussi, évidemment) java.lang.Object. Ce classloader est d'ailleurs très particulier : il est natif (donc pas écrit en Java), et on ne peut le référencer que par "(ClassLoader) null"...

Ceci étant dit, la question pose le problème du déchargement des classes, pas celui de leur chargement. Si je fais le parallèle avec les objets, auriez-vous trouvé logique la réponse «les objets ne sont jamais déchargés de la mémoire parce que le langage Java prévoit une instruction new et aucune instruction delete» ? Si le classloader est responsable du chargement des classes en mémoire, est-ce forcément lui qui doit être responsable de leur déchargement ?

3. Le jeudi 5 juin 2008, 12:57 par Histrion

En relisant la question j'ai trouvé une réponse : "Quelle classe ?"

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.