<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Thomas COURANT</title>
	<atom:link href="http://tcourant.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://tcourant.wordpress.com</link>
	<description>Java/JEE, Web, Méthodologie</description>
	<lastBuildDate>Sat, 05 Feb 2011 20:12:42 +0000</lastBuildDate>
	<language>fr</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='tcourant.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Thomas COURANT</title>
		<link>http://tcourant.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://tcourant.wordpress.com/osd.xml" title="Thomas COURANT" />
	<atom:link rel='hub' href='http://tcourant.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Glassfish V3 / JEE6 / Ear modulaire</title>
		<link>http://tcourant.wordpress.com/2011/02/04/glassfish-v3-jee6-ear-modulaire/</link>
		<comments>http://tcourant.wordpress.com/2011/02/04/glassfish-v3-jee6-ear-modulaire/#comments</comments>
		<pubDate>Fri, 04 Feb 2011 20:12:30 +0000</pubDate>
		<dc:creator>tcourant</dc:creator>
				<category><![CDATA[Java / JEE]]></category>
		<category><![CDATA[ear]]></category>
		<category><![CDATA[glassfish]]></category>
		<category><![CDATA[JEE6]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[persistence.xml]]></category>

		<guid isPermaLink="false">http://tcourant.wordpress.com/?p=77</guid>
		<description><![CDATA[Lors de mon dernier projet JEE6 avec glassfish V3, j&#8217;ai été confronté à un problème de compréhension sur la structure d&#8217;un ear. J&#8217;avais une structure modulaire avec plusieurs jars ejb gérés avec JPA. Pour être conforme avec la norme, et pour faire simple, j&#8217;ai donc adopté la structure suivante : - ear\ &#8212;- stateless_ejb1.jar &#8212;- [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tcourant.wordpress.com&amp;blog=9463088&amp;post=77&amp;subd=tcourant&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Lors de mon dernier projet JEE6 avec glassfish V3, j&#8217;ai été confronté à un problème de compréhension sur la structure d&#8217;un ear.<br />
J&#8217;avais une structure modulaire avec plusieurs jars ejb gérés avec JPA.<br />
Pour être conforme avec la norme, et pour faire simple, j&#8217;ai donc adopté la structure suivante :<br />
- ear\<br />
&#8212;- stateless_ejb1.jar<br />
&#8212;- stateless_ejb2.jar<br />
&#8212;- META-INF\<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; application.xml<br />
&#8212;- lib\<br />
&#8212;&#8212;&#8212;- log4j.jar</p>
<h3>Et maintenant où placer le fichier persistence.xml ?</h3>
<p>Il faut que le persistence-unit soit commun à tous mes ejbs. J&#8217;ai tout de suite pensé au répertoire META-INF de l&#8217;ear mais j&#8217;ai appris qu&#8217;il est ignoré dans la recherche du persistence.xml.<br />
J&#8217;ai tenté de mettre le fichier dans un nouveau projet ejb, mais il n&#8217;était pas visible des autres projets ejbs.<br />
La solution a été de packager le fichier persistence.xml dans un jar persistence.jar (ce jar contient seulement un répertoire META-INF et à l&#8217;intérieur le fichier persistence.xml) et de mettre ce fichier dans le répertoire <strong>lib</strong> de l&#8217;ear.</p>
<p>Ce qui donne :<br />
- ear\<br />
&#8212;- stateless_ejb1.jar<br />
&#8212;- stateless_ejb2.jar<br />
&#8212;- META-INF\<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; application.xml<br />
&#8212;- lib\<br />
&#8212;&#8212;&#8212;- persistence.jar<br />
&#8212;&#8212;&#8212;- log4j.jar</p>
<p>Vive la modularité&#8230;.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tcourant.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tcourant.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tcourant.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tcourant.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tcourant.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tcourant.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tcourant.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tcourant.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tcourant.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tcourant.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tcourant.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tcourant.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tcourant.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tcourant.wordpress.com/77/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tcourant.wordpress.com&amp;blog=9463088&amp;post=77&amp;subd=tcourant&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tcourant.wordpress.com/2011/02/04/glassfish-v3-jee6-ear-modulaire/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/de49ac4d0a14a8b71fb4c463cb79dfc6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tcourant</media:title>
		</media:content>
	</item>
		<item>
		<title>OutOfMemory : PermGenSpace sur des framework applicatifs (tels Glassfish ou Tomcat)</title>
		<link>http://tcourant.wordpress.com/2009/10/21/outofmemory-permgenspace-sur-des-framework-applicatifs-tels-glassfish-ou-tomcat/</link>
		<comments>http://tcourant.wordpress.com/2009/10/21/outofmemory-permgenspace-sur-des-framework-applicatifs-tels-glassfish-ou-tomcat/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 19:03:35 +0000</pubDate>
		<dc:creator>tcourant</dc:creator>
				<category><![CDATA[Java / JEE]]></category>
		<category><![CDATA[classloader]]></category>
		<category><![CDATA[fuite mémoire]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jee]]></category>
		<category><![CDATA[memory leak]]></category>
		<category><![CDATA[OutOfMemory]]></category>
		<category><![CDATA[OutOfMemoryError]]></category>
		<category><![CDATA[Permanent Generation]]></category>
		<category><![CDATA[PermGenSpace]]></category>
		<category><![CDATA[problème]]></category>
		<category><![CDATA[Tomcat]]></category>

		<guid isPermaLink="false">http://tcourant.wordpress.com/?p=40</guid>
		<description><![CDATA[Cet exception signifie qu&#8217;une application déployé sur votre framework ne libère pas les objets &#171;&#160;classe&#160;&#187; lorsqu&#8217;elle est déchargée. La zone de mémoire dite &#8216;permanent generation space&#8216; est une zone où réside les objets &#171;&#160;classe&#160;&#187;, et également toutes les chaines de caractères sur lesquels la méthode &#8216;intern()&#8216; été appelé. Une classe est chargée par un classloader, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tcourant.wordpress.com&amp;blog=9463088&amp;post=40&amp;subd=tcourant&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Cet exception signifie qu&#8217;une application déployé sur votre framework ne libère pas les objets &laquo;&nbsp;classe&nbsp;&raquo; lorsqu&#8217;elle est déchargée.</p>
<p>La zone de mémoire dite &#8216;<strong><em>permanent generation space</em></strong>&#8216; est une zone où réside les objets &laquo;&nbsp;classe&nbsp;&raquo;, et également toutes les chaines de caractères sur lesquels la méthode &#8216;<em>intern()</em>&#8216; été appelé.</p>
<p>Une classe est chargée par un classloader, une classe référence son <em>classloader </em>et le <em>classloader </em>référence toutes les classes qu&#8217;il a chargé.</p>
<p>Les frameworks applicatifs créé une nouvelle instance de <em>classloader</em> pour chaque application déployée, cela permet d&#8217;isoler les applications les unes des autres, et notamment, permet aux différentes applications d&#8217;utiliser plusieurs versions de la même classe.</p>
<p>Pour éviter toute fuite mémoire lors d&#8217;un déchargement, il faut faire attention à ce que toutes les instances des objets de l&#8217;application ne soient plus joignable, sinon le <em>Garbage Collector</em> ne libérera jamais le <em>classloader </em>et toutes les classes qu&#8217;il a chargé.</p>
<p style="text-align:left;">
<p>&nbsp;</p>
<h3>Dans quel cas cela se passe mal ?</h3>
<p>&nbsp;</p>
<p style="text-align:left;">
<p>Il faut faire attention à l&#8217;utilisation des attributs déclarés &#8216;<em>static</em>&#8216; dans les classes que nous définissons.<br />
En effet, un attribut &#8216;<em>static</em>&#8216; se trouve référencé dans l&#8217;objet classe créé par le <em>classloader</em>.</p>
<p>Disons donc que nous définissons un attribut &#8216;<em>static</em>&#8216; et que nous créons un objet dedans.<br />
Jusque la, rien de grave, car cet objet n&#8217;est référencé que par cette classe, donc le GC pourra libérer l&#8217;objet et la classe.<br />
Mais voila, si cet objet est référencé dans une autre classe, également par un attribut <em>&#8216;static&#8217;</em>, alors le GC considère l&#8217;objet comme &#8216;<em>unreachable</em>&#8216;, et ne le libère pas, et donc ne libère pas non plus la classe, ni le <em>classloader</em>, ni toutes les classes du <em>classloader</em>.<br />
<br />&nbsp;</p>
<h3>Comment diagnostiquer le problème ?</h3>
<p>&nbsp;<br />
Il faut obtenir un dump de la mémoire, soit au moment de l&#8217;<em>outofmemory </em>(option -XX:+HeapDumpOnOutOfMemoryError), soit quand vous le souhaitez avec la jconsole (outil fourni par le jdk), en ayant lancé au préalable un garbage collector manuellement (depuis la jconsole également &gt; onglet &laquo;&nbsp;memory&nbsp;&raquo; &gt; bouton &laquo;&nbsp;perform gc&nbsp;&raquo;).</p>
<p><div id="attachment_41" class="wp-caption aligncenter" style="width: 610px"><a href="http://tcourant.files.wordpress.com/2009/10/jconsole-performgc.gif" target="_blank"><img class="size-full wp-image-41    " title="jconsole-performGC" src="http://tcourant.files.wordpress.com/2009/10/jconsole-performgc.gif?w=600&#038;h=466" alt="Comment demander à la JVM de lancer un Garbage Collector" width="600" height="466" /></a><p class="wp-caption-text">Comment demander à la JVM de lancer un Garbage Collector</p></div><br />
<br />&nbsp;<br />
Une fois ce dump obtenu, il faut l&#8217;analyser, et regarder les objets de type <em>classloader</em>, et inspecter leurs attributs, notamment <em>&laquo;&nbsp;loadDir&nbsp;&raquo;</em>, qui vous donnera le chemin de l&#8217;application lié au <em>classloader</em>.</p>
<p>Vous devez avoir un seul classloader pour chaque application déployé. Si tel n&#8217;est pas le cas, vous avez une fuite mémoire.</p>
<p>Vous avez maintenant trouvé le coupable, le mieux est alors de l&#8217;isoler dans le framework applicatif, en déchargeant toutes les applications et de redémarrer le framework.</p>
<p>Lancez alors la jconsole, et se positionner sur l&#8217;onglet &#8216;classes&#8217; pour observer le nombre de classes chargées.</p>
<p><div id="attachment_42" class="wp-caption aligncenter" style="width: 610px"><a href="http://tcourant.files.wordpress.com/2009/10/jconsole-deploy.gif" target="_blank"><img class="size-full wp-image-42" title="jconsole-deploy" src="http://tcourant.files.wordpress.com/2009/10/jconsole-deploy.gif?w=600&#038;h=466" alt="jconsole-deploy" width="600" height="466" /></a><p class="wp-caption-text">Déploiement d&#39;une application</p></div><br />
<br />&nbsp;<br />
Ensuite, déchargez l&#8217;application et demander un Garbage (n&#8217;hesitez pas à en faire plusieurs à la suite).</p>
<p><div id="attachment_43" class="wp-caption aligncenter" style="width: 610px"><a href="http://tcourant.files.wordpress.com/2009/10/jconsole-undeploy-leak.gif" target="_blank"><img class="size-full wp-image-43 " title="jconsole-undeploy-leak" src="http://tcourant.files.wordpress.com/2009/10/jconsole-undeploy-leak.gif?w=600&#038;h=448" alt="Déchargement d'une application" width="600" height="448" /></a><p class="wp-caption-text">Déchargement d&#39;une application</p></div><br />
<br />&nbsp;<br />
La vous êtes sur qu&#8217;il y a une fuite mémoire, car le nombre de classe chargées n&#8217;a pas diminué suite aux multiples garbages.</p>
<p>Maintenant, vous devrez modifier le code de l&#8217;application, puis à chaque fois vérifier si cela résout le problème en refaisant la manipulation que l&#8217;on vient de faire mais cette fois en constatant une baisse du nombre de classe chargé.<br />
<br />&nbsp;</p>
<h3>Par où commencer pour résoudre le problème ?</h3>
<p>&nbsp;<br />
Soyons optimiste et disons nous que le problème vient de notre code et non d&#8217;une librairie externe que nous n&#8217;avons pas conçu nous-même.</p>
<p>D&#8217;une part, vérifier que lors du déchargement de notre application (par exemple dans la méthode &laquo;&nbsp;<em>destroy()</em>&nbsp;&raquo; d&#8217;une <em>InitServlet</em>), nous faisons correctement et totallement le ménage des objets complexes que nous utilisons.</p>
<p>Citons par exemple log4j avec &#8216;<em>LogManager.shutdown()&#8217;</em>, httpClient avec  &#8216;<em>MultiThreadedHttpConnectionManager.shutdownAll()</em>&#8216;, <em>JMX </em>et le desenregistrement de nos <em>mbeans</em>, l&#8217;arrêt de notre pool de thread,  etc&#8230;</p>
<p>Ensuite, faites une recherche de tous les attributs <em>static </em>de l&#8217;application, et si possible, faites une méthode <em>shutdown() </em>si les attributs ou objets sont plutôt complexe et peuvent contenir beaucoup d&#8217;objets. Cela facilitera le travail du Garbage Collector, et surtout vérifier qu&#8217;il n&#8217;y a pas de cas problématique (voir plus haut) où un objet est référencé dans plus d&#8217;un attribut static.<br />
<br />&nbsp;</p>
<h3>Pendant que vous y êtes&#8230;</h3>
<p>&nbsp;<br />
Vérifier également la gestion des <em>threads </em>lors des déploiments / déchargement de votre application.</p>
<p>Pour cela, utiliser la jconsole &gt;&gt; onglet &#8216;Threads&#8217;, et étudier la courbe &#8216;Live threads&#8217;. Effectuer plusieurs déploiements / déchargements consécutifs. La courbe ne doit pas monter, car alors cela signifie que des threads ne sont pas stoppé lors du déchargement.</p>
<p><div id="attachment_44" class="wp-caption aligncenter" style="width: 610px"><a href="http://tcourant.files.wordpress.com/2009/10/jconsole-threads.gif" target="_blank"><img class="size-full wp-image-44 " title="jconsole-threads" src="http://tcourant.files.wordpress.com/2009/10/jconsole-threads.gif?w=600&#038;h=500" alt="Visualiser le nombre de threads" width="600" height="500" /></a><p class="wp-caption-text">Visualiser le nombre de threads</p></div><br />
<br />&nbsp;<br />
Excellent document sur la &#8216;<em>permanent generation space</em>&#8216; et l&#8217;<em>OutOfMemory </em>: <a href="http://mediacast.sun.com/users/Frank.Kieviet/media/JavaOne07-BOF9982-PermGen.pdf" target="_blank">http://mediacast.sun.com/users/Frank.Kieviet/media/JavaOne07-BOF9982-PermGen.pdf</a><br />
<br />&nbsp;</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tcourant.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tcourant.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tcourant.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tcourant.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tcourant.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tcourant.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tcourant.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tcourant.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tcourant.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tcourant.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tcourant.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tcourant.wordpress.com/40/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tcourant.wordpress.com/40/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tcourant.wordpress.com/40/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tcourant.wordpress.com&amp;blog=9463088&amp;post=40&amp;subd=tcourant&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tcourant.wordpress.com/2009/10/21/outofmemory-permgenspace-sur-des-framework-applicatifs-tels-glassfish-ou-tomcat/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/de49ac4d0a14a8b71fb4c463cb79dfc6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tcourant</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/10/jconsole-performgc.gif" medium="image">
			<media:title type="html">jconsole-performGC</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/10/jconsole-deploy.gif" medium="image">
			<media:title type="html">jconsole-deploy</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/10/jconsole-undeploy-leak.gif" medium="image">
			<media:title type="html">jconsole-undeploy-leak</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/10/jconsole-threads.gif" medium="image">
			<media:title type="html">jconsole-threads</media:title>
		</media:content>
	</item>
		<item>
		<title>Analyse de la mémoire d&#8217;une application Java</title>
		<link>http://tcourant.wordpress.com/2009/09/14/analyse-de-la-memoire-dune-application-java/</link>
		<comments>http://tcourant.wordpress.com/2009/09/14/analyse-de-la-memoire-dune-application-java/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 19:12:24 +0000</pubDate>
		<dc:creator>tcourant</dc:creator>
				<category><![CDATA[Java / JEE]]></category>
		<category><![CDATA[dump]]></category>
		<category><![CDATA[eclipse memory analyser]]></category>
		<category><![CDATA[fuite mémoire]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jee]]></category>
		<category><![CDATA[jhat]]></category>
		<category><![CDATA[memory leak]]></category>
		<category><![CDATA[OutOfMemory]]></category>
		<category><![CDATA[OutOfMemoryError]]></category>
		<category><![CDATA[problème]]></category>
		<category><![CDATA[Tomcat]]></category>

		<guid isPermaLink="false">http://tcourant.wordpress.com/?p=3</guid>
		<description><![CDATA[Lorsque vous voulez analyser la mémoire de votre programme java, le jdk 6 propose des outils puissants et relativement simples à utiliser. Pré-requis : Il vous faut le jdk5 minimum. Il vous faut télécharger le plugin &#8216;eclipse memory analyzer&#8216; pour Eclipse, à installer depuis cet url http://download.eclipse.org/technology/mat/0.8/update-site/ à saisir dans le menu d&#8217;aide d&#8217;Eclipse, puis [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tcourant.wordpress.com&amp;blog=9463088&amp;post=3&amp;subd=tcourant&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Lorsque vous voulez analyser la mémoire de votre programme java, le jdk 6 propose des outils puissants et relativement simples à utiliser.</p>
<h3>Pré-requis<strong> :</strong></h3>
<p>Il vous faut le jdk5 minimum.<br />
Il vous faut télécharger le plugin &#8216;<strong>eclipse memory analyzer</strong>&#8216; pour Eclipse, à installer depuis cet url <a title="http://download.eclipse.org/technology/mat/0.8/update-site/" href="http://download.eclipse.org/technology/mat/0.8/update-site/">http://download.eclipse.org/technology/mat/0.8/update-site/</a> à saisir dans le menu d&#8217;aide d&#8217;Eclipse, puis &#8216;mise à jour&#8217;.</p>
<p>La plupart des nouvelles fonctions de supervision sont regroupé via l&#8217;interface JMX, c&#8217;est pour cela qu&#8217;il est nécessaire d&#8217;activer JMX sur votre programme.</p>
<p>Pour cela, dans les options de ligne de commande du lancement de votre application, rajouter les options:</p>
<pre style="text-align:justify;">-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8084
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false</pre>
<p>indiquant à la JVM d&#8217;activer JMX sans authentification et accessible via le port 8084 (que vous pouvez changer bien sur).</p>
<h2>1ère étape : Obtenir un dump de la mémoire</h2>
<p>Il existe plusieurs façons d&#8217;obtenir un dump :</p>
<ul>
<li> Utilisation de la console JMX fournie avec le jdk</li>
</ul>
<p>Dans un shell, tapez &#8216;<strong>jconsole</strong>&#8216;.</p>
<div id="attachment_9" class="wp-caption aligncenter" style="width: 346px"><a href="http://tcourant.files.wordpress.com/2009/09/jconsole-login2.gif" target="_blank"><img class="size-full wp-image-9  " title="jconsole-login" src="http://tcourant.files.wordpress.com/2009/09/jconsole-login2.gif?w=336&#038;h=280" alt="login de la jconsole" width="336" height="280" /></a><p class="wp-caption-text">login de la jconsole</p></div>
<p>Cochez &#8216;<strong>Remote Process</strong>&#8216;, et saisir &#8216;<strong>localhost:8084</strong>&#8216; et cliquer sur &#8216;<strong>connect</strong>&#8216;.<br />
Ensuite dans l&#8217;onglet &#8216;<strong>MBeans</strong>&#8216;, déroulez dans le menu de gauche la partie &#8216;<strong>com.sun.management.HotSpotDiagnostic.Operations</strong>&#8216; et sur la partie de droite, apparait une méthode &#8216;<strong>dumpHeap</strong>&#8216;.</p>
<p style="text-align:left;">
<div id="attachment_14" class="wp-caption aligncenter" style="width: 346px"><a href="http://tcourant.files.wordpress.com/2009/09/jconsole-dumpheap.gif" target="_blank"><img class="size-full wp-image-14 " title="jconsole-dumpHeap" src="http://tcourant.files.wordpress.com/2009/09/jconsole-dumpheap.gif?w=336&#038;h=272" alt="Dumper la mémoire" width="336" height="272" /></a><p class="wp-caption-text">Dumper la mémoire</p></div>
<p>Le paramètre &#8216;<strong>P0</strong>&#8216; représente le chemin du fichier dump sur le disque à générer, et le paramètre &#8216;<strong>p1</strong>&#8216; doit rester à ‘<strong>true</strong>’, signifiant par cette valeur que nous voulons uniquement les objets vivants.<br />
Appuyez sur le bouton &#8216;<strong>dumpHeap</strong>&#8216; et le fichier se génère à l&#8217;endroit spécifié.</p>
<p style="text-align:left;">
<ul>
<li> Configurer notre programme java pour générer un dump lors d&#8217;une exception ‘<strong>OutOfMemoryError</strong>’.</li>
</ul>
<p>Pour cela, il faut rajouter dans les options du programme &#8216;<strong>-XX:+HeapDumpOnOutOfMemoryError</strong>&#8216;. Il générera un fichier de type &laquo;&nbsp;j<strong>ava_pidXXX.hprof</strong>&nbsp;&raquo; à la racine de votre application.</p>
<ul>
<li> Utiliser l&#8217;outil &#8216;<strong>jmap</strong>&#8216; fourni par le jdk.</li>
</ul>
<p style="text-align:left;">Dans un shell, tapez &#8216;<strong>jmap -dump:format=b,file=<em>&lt;fichier&gt;</em> &lt;<em>pid&gt;</em></strong>&#8216; où &lt;<strong>pid&gt; </strong>est l&#8217;identifiant du process faisant tourner votre application et &lt;<strong>fichier</strong>&gt; est le chemin vers le fichier de dump sur le disque.<br />
Sur un environnement 64bits, cette commande ne fonctionne pas, privilégiez alors JMX et la jconsole.</p>
<p style="text-align:left;">
<h2>2eme étape : Analyser le dump</h2>
<p>Il existe plusieurs façons d&#8217;analyser un dump, mais un fichier dump ne peut se lire avec un éditeur de texte, car c&#8217;est du binaire.</p>
<ul>
<li> Utiliser le plugin &#8216;<strong>Memory analyzer</strong>&#8216; sous Eclipse.</li>
</ul>
<p>Pour cela, il faut sélectionner la perspective du plugin, et ensuite cliquer sur le bouton pour ouvrir un fichier de dump.</p>
<p style="text-align:left;">
<div id="attachment_15" class="wp-caption aligncenter" style="width: 346px"><a href="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer.gif" target="_blank"><img class="size-full wp-image-15 " title="eclipse-memory-analyzer" src="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer.gif?w=336&#038;h=218" alt="Plugin memory analyser" width="336" height="218" /></a><p class="wp-caption-text">Plugin memory analyser</p></div>
<p>Ensuite, il faut se laisser guider par le plugin. L&#8217;aide du plugin est très bien faite.<br />
Pour commencer, dans le wizard qu&#8217;on nous propose, choisir &#8216;<strong>Leak Suspects report</strong>&#8216; et cliquez sur &#8216;<strong>Finish</strong>&#8216;. Cette opération va déclencher une recherche des fuites mémoires possibles.</p>
<p style="text-align:center;">
<div id="attachment_16" class="wp-caption aligncenter" style="width: 346px"><a href="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-leak.gif" target="_blank"><img class="size-full wp-image-16 " title="eclipse-memory-analyzer-leak" src="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-leak.gif?w=336&#038;h=262" alt="Fuite mémoire" width="336" height="262" /></a><p class="wp-caption-text">Fuite mémoire</p></div>
<p>Le rapport ainsi produit nous indique clairement un problème avec des objets de type &laquo;&nbsp;<strong>Classloader</strong>&nbsp;&raquo; (problème typique dans des serveurs d&#8217;applications comme Tomcat).<br />
Le gros du travail reste alors à faire, c&#8217;est à dire trouver pourquoi ces objets posent problème.<br />
Le plugin propose également d&#8217;autres rapport intéressants:</p>
<p style="text-align:center;">
<div id="attachment_17" class="wp-caption aligncenter" style="width: 346px"><a href="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-overview.gif" target="_blank"><img class="size-full wp-image-17 " title="eclipse-memory-analyzer-overview" src="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-overview.gif?w=336&#038;h=218" alt="Tableau de bord" width="336" height="218" /></a><p class="wp-caption-text">Tableau de bord</p></div>
<p>Le rapport &#8216;<strong>Histogram</strong>&#8216; liste l&#8217;ensemble des classes de la mémoire, en nous précisant le nombre d&#8217;instances de chaque classe, le nombre d&#8217;octets pris par l&#8217;ensemble des objets de chaque classe (shallow heap) en comptabilisant les pointeurs directs uniquement, et enfin le nombre d&#8217;octets pris par l&#8217;ensemble des instances de classe en comptant cette fois en profondeur tous les objets contenus dans chaque instance (retained heap).</p>
<p>Par exemple, prenons le cas de la classe <em>ArrayList</em>. Cette classe contient principalement un tableau d&#8217;objets.<br />
La &#8216;shallow heap&#8217; d&#8217;un objet <em>ArrayList </em>est donc grosso modo équivalent à : taille du tableau * taille d&#8217;un pointeur (32 ou 64 bits suivant l&#8217;os).<br />
La &#8216;retained heap&#8217; d&#8217;un objet <em>ArrayList </em>correspond à la somme de tous les &#8216;shallow heap&#8217; de l&#8217;ensemble des objets rattachés à cet objet. Prenons le cas d&#8217;un objet <em>ArrayList </em>de String, la retained heap est équivalent à : shallow heap de l&#8217;<em>ArrayList </em>+ taille du tableau * retained heap d&#8217;un String.etc&#8230;</p>
<p style="text-align:center;">
<div id="attachment_18" class="wp-caption aligncenter" style="width: 345px"><a href="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-histogram.gif" target="_blank"><img class="size-full wp-image-18 " title="eclipse-memory-analyzer-histogram" src="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-histogram.gif?w=335&#038;h=221" alt="Histogram" width="335" height="221" /></a><p class="wp-caption-text">Histogram</p></div>
<p>Le rapport &#8216;<strong>Dominator tree</strong>&#8216; liste l&#8217;ensemble des objets, ce qui nous permet de voir quels sont les objets qui prennent le plus de place en mémoire.</p>
<p style="text-align:center;">
<div id="attachment_19" class="wp-caption aligncenter" style="width: 345px"><a href="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-dominator-tree.gif" target="_blank"><img class="size-full wp-image-19 " title="eclipse-memory-analyzer-dominator-tree" src="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-dominator-tree.gif?w=335&#038;h=221" alt="Dominator Tree" width="335" height="221" /></a><p class="wp-caption-text">Dominator Tree</p></div>
<p>Ainsi, sur la capture ci dessus, on voit que l&#8217;objet &#8216;<em>org.apache.catalina.loader.WebappClassLoader @ 0x68c1c60&#8242;</em> prend pas moins de <strong>1,7 megaoctets</strong> à lui seul.<br />
Lorsque l&#8217;on clique sur un objet, on peut voir dans l&#8217;onglet &#8216;<strong>attributes</strong>&#8216; les attributs de l&#8217;objet.</p>
<p>Enfin, le rapport &#8216;<strong>Duplicate classes</strong>&#8216; nous indique les mêmes classes qui ont été chargés en plusieurs exemplaire, ce qui permet de nous éclairer sur des optimisations à faire, et sur des problemes de classloader.</p>
<h3>Quelques trucs et astuces sur l&#8217;utilisation de ce plugin :</h3>
<p style="text-align:left;">Sur un objet ou une classe, appuyez sur le bouton droit de la souris et un menu apparait.<br />
Si vous voulez connaître les classes qui référencent l&#8217;objet que vous avez sélectionné, choisissez &#8216;<strong>Show Objects by class</strong> &gt; <strong>by incoming references</strong>&#8216;.</p>
<div id="attachment_20" class="wp-caption aligncenter" style="width: 345px"><a href="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-incoming-ref.gif" target="_blank"><img class="size-full wp-image-20   " title="eclipse-memory-analyzer-incoming-ref" src="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-incoming-ref.gif?w=335&#038;h=227" alt="Incoming reference" width="335" height="227" /></a><p class="wp-caption-text">Incoming reference</p></div>
<p>Dans la capture, on peut voir que la classe &#8216;<em>java.util.ArrayList</em>&#8216; est utilisée dans la classe &#8216;<em>java.beans.MethodDescriptor</em>&#8216;.</p>
<p>Si vous voulez connaître les objets que sont référencés par l&#8217;objet que vous avez sélectionné, choisissez &#8216;<strong>List Objects </strong>&gt; <strong>with outgoing references</strong>&#8216;.</p>
<p style="text-align:left;">
<div id="attachment_21" class="wp-caption aligncenter" style="width: 345px"><a href="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-outgoing-ref.gif" target="_blank"><img class="size-full wp-image-21 " title="eclipse-memory-analyzer-outgoing-ref" src="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-outgoing-ref.gif?w=335&#038;h=227" alt="Outgoing reference" width="335" height="227" /></a><p class="wp-caption-text">Outgoing reference</p></div>
<p>Dans cette capture, on peut voir tous les objets en attributs direct de l&#8217;objet sélectionné, et voir la taille. Par exemple, on voit que c&#8217;est une ‘hashtable’ qui prend la majorité de la mémoire de l&#8217;objet sélectionné.</p>
<ul>
<li> Utiliser l&#8217;outil &#8216;<strong>jhat</strong>&#8216; du jdk qui donne les mêmes informations que le plugin Eclipse mais ces informations parcours à l&#8217;aide d&#8217;un navigateur web, et l&#8217;ergonomie en patie. Les leaks ne sont pas indiqués, c&#8217;est à nous de les trouver.</li>
</ul>
<p>Dans un shell, tapez &#8216;<strong>jhat -J-Xmx512m &lt;fichier de dump sur le disque&gt;</strong>&#8216;. Je passe une valeur xmx car si le fichier de dump est gros, il faut de la mémoire pour l&#8217;analyser.<br />
jhat analyse alors le dump, et lance un mini serveur web sur le port 7000. Il ne reste plus qu&#8217;à lancer un navigateur web à l&#8217;adresse &#8216;http://localhost:7000&#8242; pour voir apparaître cet écran.</p>
<p style="text-align:left;">
<div id="attachment_22" class="wp-caption aligncenter" style="width: 346px"><a href="http://tcourant.files.wordpress.com/2009/09/jhat-main.gif" target="_blank"><img class="size-full wp-image-22 " title="jhat-main" src="http://tcourant.files.wordpress.com/2009/09/jhat-main.gif?w=336&#038;h=294" alt="jhat" width="336" height="294" /></a><p class="wp-caption-text">jhat</p></div>
<p>On retrouve certaines opérations disponibles dans le plugin eclipse, comme la partie &#8216;<strong>histogram</strong>&#8216;.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tcourant.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tcourant.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/tcourant.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/tcourant.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/tcourant.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/tcourant.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/tcourant.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/tcourant.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/tcourant.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/tcourant.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/tcourant.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/tcourant.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/tcourant.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/tcourant.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tcourant.wordpress.com&amp;blog=9463088&amp;post=3&amp;subd=tcourant&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tcourant.wordpress.com/2009/09/14/analyse-de-la-memoire-dune-application-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/de49ac4d0a14a8b71fb4c463cb79dfc6?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tcourant</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/09/jconsole-login2.gif" medium="image">
			<media:title type="html">jconsole-login</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/09/jconsole-dumpheap.gif" medium="image">
			<media:title type="html">jconsole-dumpHeap</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer.gif" medium="image">
			<media:title type="html">eclipse-memory-analyzer</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-leak.gif" medium="image">
			<media:title type="html">eclipse-memory-analyzer-leak</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-overview.gif" medium="image">
			<media:title type="html">eclipse-memory-analyzer-overview</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-histogram.gif" medium="image">
			<media:title type="html">eclipse-memory-analyzer-histogram</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-dominator-tree.gif" medium="image">
			<media:title type="html">eclipse-memory-analyzer-dominator-tree</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-incoming-ref.gif" medium="image">
			<media:title type="html">eclipse-memory-analyzer-incoming-ref</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/09/eclipse-memory-analyzer-outgoing-ref.gif" medium="image">
			<media:title type="html">eclipse-memory-analyzer-outgoing-ref</media:title>
		</media:content>

		<media:content url="http://tcourant.files.wordpress.com/2009/09/jhat-main.gif" medium="image">
			<media:title type="html">jhat-main</media:title>
		</media:content>
	</item>
	</channel>
</rss>
