<?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/"
	>

<channel>
	<title>Communardo Techblog &#187; jvm</title>
	<atom:link href="http://www.communardo.de/home/techblog/tag/jvm/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.communardo.de/home/techblog</link>
	<description></description>
	<lastBuildDate>Wed, 10 Mar 2010 18:30:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>de</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Verwendung von Java2 5.0 Klassen mit Java2 1.4 mit Retrotranslator</title>
		<link>http://www.communardo.de/home/techblog/2008/01/07/verwendung-von-java2-50-klassen-mit-java2-14-mit-retrotranslator/</link>
		<comments>http://www.communardo.de/home/techblog/2008/01/07/verwendung-von-java2-50-klassen-mit-java2-14-mit-retrotranslator/#comments</comments>
		<pubDate>Mon, 07 Jan 2008 16:23:11 +0000</pubDate>
		<dc:creator>jdi</dc:creator>
				<category><![CDATA[JEE]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jaxb]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[maven2]]></category>
		<category><![CDATA[retrotranslator]]></category>
		<category><![CDATA[webservice]]></category>
		<category><![CDATA[xfire]]></category>

		<guid isPermaLink="false">http://www.communardo.de/techblog/2008/01/07/verwendung-von-java2-50-klassen-mit-java2-14-mit-retrotranslator/</guid>
		<description><![CDATA[<img alt="jdi" src="http://www.communardo.de/home/wp-content/filebase/defaults/default_gravatar.jpg" class="com-blog-icon"/><a href="http://www.communardo.de/home/techblog/author/jdi/" title="Artikel von jdi">jdi</a><p>In einem existierenden Java2 1.4 Projekt sollen generierte XFire-Clientklassen verwendet werden. Der XFire-Codegenerator verwendet JAXB2 und ist damit auf einige Java2 5.0-Features wie Annotations angewiesen. Der Umstieg auf Java2 5.0 ist in dem Projekt keine Option und deshalb habe ich eine M&#246;glichkeit gebraucht, die generierten Klassen mit Java2 1.4 zu verwenden.</p>
<p>Nach ein paar Recherchen habe ich mich f&#252;r die Verwendung des freien <a href="http://retrotranslator.sourceforge.net/" title="Retrotranslator Java2 5.0 Bytecode zu Java2 1.4 Bytecode Translator">Retrotranslator</a>-Tools entschieden und eine Proof-Of-Concept-Implementierung realisiert. Retrotranslator kann sowohl zur Compile-Zeit als auch zur Laufzeit den Java2 5.0 Bytecode in Java2 1.4 Bytecode umwandeln. F&#252;r den eigenen Code habe ich mich f&#252;r die Umwandlung zur Compilezeit entschieden und f&#252;r verwendeten Code Dritter f&#252;r die Umwandlung zur Laufzeit (Just in Time Compilierung).</p>
<p>Nun zur praktischen Umsetzung mit Maven2:</p>
<p>Das POM des Codegenerierungsprojektes sieht folgenderma&#223;en aus:</p>
<pre>&lt;project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;de.communardo.techblog&lt;/groupId&gt;
  &lt;artifactId&gt;demoxfiregen&lt;/artifactId&gt;
  &lt;packaging&gt;jar&lt;/packaging&gt;
  &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
  &lt;name&gt;Generierter XFire-Code fuer Communardo Techblog&lt;/name&gt;

  &lt;build&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
        &lt;configuration&gt;
          &lt;source&gt;1.5&lt;/source&gt;
          &lt;target&gt;1.5&lt;/target&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
        &lt;artifactId&gt;xfire-maven-plugin&lt;/artifactId&gt;
        &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;goals&gt;
              &lt;goal&gt;wsgen&lt;/goal&gt;
            &lt;/goals&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
        &lt;configuration&gt;
          &lt;package&gt;
            de.communardo.techblog.services
          &lt;/package&gt;
          &lt;profile /&gt;
          &lt;binding /&gt;
          &lt;outputDirectory&gt;
            ${project.build.directory}/generated-sources/xfire
          &lt;/outputDirectory&gt;
          &lt;wsdls&gt;
            &lt;wsdl&gt;
              ${basedir}/src/main/resources/TechblogDemoService.wsdl
            &lt;/wsdl&gt;
          &lt;/wsdls&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
        &lt;artifactId&gt;retrotranslator-maven-plugin&lt;/artifactId&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;phase&gt;package&lt;/phase&gt;
            &lt;goals&gt;
              &lt;goal&gt;translate-project&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
              &lt;classifier&gt;jdk14&lt;/classifier&gt;
              &lt;attach&gt;true&lt;/attach&gt;
              &lt;embed&gt;net.sf.retrotranslator&lt;/embed&gt;
            &lt;/configuration&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;

  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.codehaus.xfire&lt;/groupId&gt;
      &lt;artifactId&gt;xfire-jaxb2&lt;/artifactId&gt;
      &lt;version&gt;1.2.5&lt;/version&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
&lt;/project&gt;</pre>
<p>Der erste Plugin-Aufruf setzt die Java-Version auf 1.5, der Zweite generiert den Java-Code aus einer WSDL und der dritte generiert in der package-Phase von Maven ein Java2 1.4 kompatibles JAR-Archiv mit dem Classifier jdk14. Mit</p>
<p><code>mvn install</code></p>
<p>wird alles gebaut und ins lokale Maven-Repository installiert.</p>
<p>Im Java2 1.4-Projekt wird das generierte JAR in den Dependencies so referenziert:</p>
<pre>    &lt;dependency&gt;
      &lt;groupId&gt;de.communardo.techblog&lt;/groupId&gt;
      &lt;artifactId&gt;demoxfiregen&lt;/artifactId&gt;
      &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
      &lt;classifier&gt;jdk14&lt;/classifier&gt;
    &lt;/dependency&gt;</pre>
<p>Um alle Abh&#228;ngigkeiten, die von XFire und den JAXB2-Klassen ben&#246;tigt werden zu erf&#252;llen und den Retrotranslator Just-In-Time-Compiler (JIT) vef&#252;gbar zu machen, wurden noch folgende Dependencies in das Ziel-POM eingetragen:</p>
<pre>    &lt;dependency&gt;
      &lt;groupId&gt;net.sf.retrotranslator&lt;/groupId&gt;
      &lt;artifactId&gt;retrotranslator-transformer&lt;/artifactId&gt;
      &lt;version&gt;1.2.1&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;javax.xml.parsers&lt;/groupId&gt;
      &lt;artifactId&gt;jaxp-api&lt;/artifactId&gt;
      &lt;version&gt;1.4&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;com.sun.org.apache&lt;/groupId&gt;
      &lt;artifactId&gt;jaxp-ri&lt;/artifactId&gt;
      &lt;version&gt;1.4&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;xerces&lt;/groupId&gt;
      &lt;artifactId&gt;xercesImpl&lt;/artifactId&gt;
      &lt;version&gt;2.8.1&lt;/version&gt;
    &lt;/dependency&gt;</pre>
<p>Damit das Ganze dann zur Laufzeit funktioniert muss beim Start der Applikation der Retrotranslator JIT genutzt werden, das geschieht in dem man die JVM-Kommandozeile folgenderma&#223;en aufbaut:</p>
<p><code>java &lt;JVM-Parameter&gt; net.sf.retrotranslator.transformer.JITRetrotranslator &lt;Main-Klasse&gt; &lt;Anwendungsparameter&gt;</code></p>
]]></description>
		<wfw:commentRss>http://www.communardo.de/home/techblog/2008/01/07/verwendung-von-java2-50-klassen-mit-java2-14-mit-retrotranslator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Was tun bei OutOfMemory &#8211; Teil 1: Grundlagen</title>
		<link>http://www.communardo.de/home/techblog/2007/12/30/was-tun-bei-outofmemory-teil-1-grundlagen/</link>
		<comments>http://www.communardo.de/home/techblog/2007/12/30/was-tun-bei-outofmemory-teil-1-grundlagen/#comments</comments>
		<pubDate>Sun, 30 Dec 2007 20:38:19 +0000</pubDate>
		<dc:creator>mse</dc:creator>
				<category><![CDATA[CoreMedia]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[OutOfMemory]]></category>

		<guid isPermaLink="false">http://www.communardo.de/techblog/2007/12/30/was-tun-bei-outofmemory-teil-1-grundlagen/</guid>
		<description><![CDATA[<img alt="mse" src="http://www.communardo.de/home/wp-content/filebase/defaults/default_gravatar.jpg" class="com-blog-icon"/><a href="http://www.communardo.de/home/techblog/author/mse/" title="Artikel von mse">mse</a><p><strong><em>OutOfMemory ist eines der am h&#228;ufigsten auftretenden Probleme bei Java-basierten Webapplikationen. Die Ursachen daf&#252;r sind genau so vielschichtig wie die M&#246;glichkeiten der Analyse. Ziel dieses Artikels ist es, sowohl die Grundlagen wie auch m&#246;gliche L&#246;sungswege zu zeigen.</em></strong></p>
<p>Bevor man jetzt leichtfertig die Software umprogrammiert (da man ja genau wei&#223;, wo das Problem liegt), sollte man mit einer ausf&#252;hrlichen Analyse beginnen. Nicht selten kommt es vor, dass Software (Parameter der JVM) oder sogar das Betriebssystem nicht korrekt konfiguriert sind.</p>
<h3>Die Process Size</h3>
<p>Die Process Size ist der maximal verf&#252;gbare Speicher f&#252;r den Prozess. Dieser ist abh&#228;ngig von der Hardware und vom Betriebssystem. In einer 32 Bit-Architektur kann die Process Size maximal 4 GB sein. F&#252;r einen Java-Prozess gibt es folgende Bereiche, die im Speicher des Prozesses liegen (siehe Abbildung 1):</p>
<ul>
<li><em><strong>Java Heap </strong></em>- Der Heap ist der Speicher, in dem die Java Objekte erzeugt und verwaltet werden.</li>
<li><em><strong>Permanent Generation</strong></em> &#8211; Die Permanent Generation ist der Speicher, in dem die JVM sich selber verwaltet. In diesem Speicher werden auch die Klassen durch den ClassLoader geladen.</li>
<li><em><strong>Nativ Code</strong></em> &#8211; Jeder Java-Prozess ben&#246;tigt auch Speicher f&#252;r den Native Code. Das sind C-Bibliotheken des Betriebssystems f&#252;r den Zugriff auf Systemressourcen. Zum Beispiel der Zugriff aufs Dateisystem.</li>
</ul>
<p><img src="http://www.communardo.de/home/techblog/files/2007/12/processsize3.png" border="0" alt="" /></p>
<p><em><strong>Abbildung 1:</strong> Schematischer Aufbau der Speicherverteilung eines Java-Prozesses</em></p>
<p>Der Speicher f&#252;r den Native Code ist nicht explizit einstellbar. Er ergibt sich aus der Differenz zwischen Process Size, Heap und Permanent Generation. Dieser Speicher darf nicht zu knapp bemessen sein, denn es kann auch OutOfMemory im Native Code geben.</p>
<h3>Die Java Heap Size</h3>
<p>Die Java Heap Size gibt die Gr&#246;&#223;e des Speichers an, der f&#252;r die Erzeugung und Verwaltung der Java-Objekte verwendet werden kann. Die Gr&#246;&#223;e des Heaps ist begrenzt. Wird keine Gr&#246;&#223;e explizit angegeben, wird die Defaulteinstellung verwendet. Diese variiert von Betriebssystem zu Betriebssystem. Wenn man wirklich sicher gehen m&#246;chte, stellt man die Gr&#246;&#223;e explizit ein:</p>
<ol><strong><code>-Xms[Bytes]m</code></strong> : initiale Gr&#246;&#223;e des Heaps beim Starten des Prozesses<br />
<strong><code>-Xmx[Bytes]m</code></strong> : maximale Gr&#246;&#223;e des Heaps &#252;ber den gesamten Lebenszeitraum</ol>
<p>Der Heap teilt sich in zwei gro&#223;e Bereiche: der New Generation und der Old Generation (siehe Abbildung 2).<br />
Wie die Namen schon vermuten lassen, befinden sich in der New Generation die ganzen neuen, jungen und kurzlebigen Java-Objekte und in der Old Generation die langlebigen Java-Objekte.</p>
<p><img src="http://www.communardo.de/home/techblog/files/2007/12/heap.png" alt="" /></p>
<p><em><strong>Abbildung 2:</strong> Aufteilung der Speicherbereiche im Heap</em></p>
<p>Das Verh&#228;ltnis zwischen New und Old Generation ist aus Speichersicht der gr&#246;&#223;te Unterschied zwischen einer Desktop- und einer Serveranwendung. Eine Desktopanwendung l&#228;uft in der Regel einen Arbeitstag, also ca. 8 h. Eine Serveranwendung l&#228;uft 24 h, 7 Tage die Woche und das mehrere Monate. Daran kann man schon erkennen, dass es bei einer Desktopanwendung mehr j&#252;ngere Objekte und bei einer Serveranwendung mehr &#228;ltere Objekte gibt. Mit dem Servermodus stellt man das Verh&#228;ltnis zwischen New und Old Generation auf <strong>1:3</strong> ein.</p>
<ol><code>-server</code> :Servermodus f&#252;r die VM</ol>
<h3>Permanent Generation</h3>
<p>Die Permanent Generation wird von der JVM f&#252;r das Laden der Klassen durch den ClassLoader verwendet. Normalerweise ist die Defaulteinstellung der Gr&#246;&#223;e ausreichend. Wenn allerdings viele Klassen dynamisch durch die Applikation geladen werden (z.B. durch Reflection), kann die Defaulteinstellung zu Problemen f&#252;hren. Auch die Verwendung von Persistenz- oder Caching-Frameworks f&#252;hrt zu gr&#246;&#223;erem Speicherverbrauch in der Permanent Generation.<br />
&#220;ber folgende Parameter kann die Defaultgr&#246;&#223;e der Permanent Generation angepasst werden:</p>
<ol><code>-XX:PermSize=[Bytes]m :</code> initiale Gr&#246;&#223;e der Permanent Generation<br />
<code>-XX:MaxPermSize=[Bytes]m :</code> maximale Gr&#246;&#223;e der Permanent Generation</ol>
<h3>Garbage Collection</h3>
<p>Man unterscheidet bei der Garbage Collection in die („einfache“) Garbage Collection und in die Full Garbage Collection. Bei der Garbage Collection werden nicht mehr referenzierte Objekte aus der New Generation freigegeben. Des Weiteren werden noch „lebende“ Objekte, die durch mehrere Garbage Collection nicht freigegeben wurden, in die Old Generation kopiert. Bei einer Full Garbage Collection werden auch Objekte aus der Old Generation aufger&#228;umt.<br />
Eine Full Garbage Collection ist sehr zeitintensiv (bei 2 GB Heap Size = mehrere Sekunden). W&#228;hrend dieser Zeit reagiert die Applikation nicht mehr.<br />
Ist die Heap Size zu gering eingestellt, findet eine Full Garbage Collection nach der anderen statt. Dies f&#252;hrt zu einer sehr schlechten Performance und zu langen Antwortszeiten.<br />
In einer Multiprozessor-Maschine ist es deshalb ratsam, die Garbage Collection („einfache“ und Full) parallel arbeiten zu lassen.</p>
<ol><code>-XX:+UseParallelGC: </code>parallele Garbage Collection und Full Garbage Collection</ol>
<h3>Ausblick</h3>
<p>Nachdem in diesem Artikel die Grundlagen erl&#228;utert wurden, werden im n&#228;chsten Artikel konkrete Analyse-M&#246;glichkeiten besprochen.</p>
<h3>Links</h3>
<ul>
<li><a title="View Systemanalyse von OutOfMemory Fehlern in Java-Anwendungen on SlideShare" href="http://www.slideshare.net/communardo/systemanalyse-von-outofmemory-fehlern-in-javaanwendungen?src=embed">Systemanalyse von OutOfMemory Fehlern in Java-Anwendungen</a></li>
</ul>
]]></description>
		<wfw:commentRss>http://www.communardo.de/home/techblog/2007/12/30/was-tun-bei-outofmemory-teil-1-grundlagen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
