<?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>blog.smart-java.nl &#187; Debugging</title>
	<atom:link href="http://blog.smart-java.nl/blog/index.php/category/debugging/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.smart-java.nl/blog</link>
	<description>Ordina J-Technologies - Java Blog</description>
	<lastBuildDate>Wed, 05 May 2010 20:06:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Boekbespreking: Code Complete, 2nd Edition</title>
		<link>http://blog.smart-java.nl/blog/index.php/2009/01/21/boekbespreking-code-complete-2nd-edition/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2009/01/21/boekbespreking-code-complete-2nd-edition/#comments</comments>
		<pubDate>Wed, 21 Jan 2009 16:06:15 +0000</pubDate>
		<dc:creator>Hedzer Westra</dc:creator>
				<category><![CDATA[Boeken]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Methodologieën]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[patterns]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/blog/?p=282</guid>
		<description><![CDATA[
 
Auteur: Steve McConnell, publicatiejaar: 2004, pagina’s: 906, ISBN-13: 978-0735619678, website: http://www.cc2e.com/, Amazon rating: 5 sterren.
 
Code Complete was me jaren geleden aangeraden als hét boek (‘de bijbel’) om te leren nette code te produceren. Enige tijd geleden (!) is de tweede editie uitgekomen, wat me een goed moment leek om deze eens te bestuderen. Het viel [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;"><a href="http://blog.smart-java.nl/blog/wp-content/uploads/2009/01/cc2e.bmp"><img class="alignnone size-medium wp-image-283" title="cc2e" src="http://blog.smart-java.nl/blog/wp-content/uploads/2009/01/cc2e.bmp" alt="" /></a></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;">Auteur:<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> Steve McConnell</span>, publicatiejaar: 2004, pagina’s: 906, ISBN-13: 978-0735619678, website: <span style="mso-ansi-language: EN-US;" lang="EN-US"><a href="http://www.cc2e.com/"><span style="mso-ansi-language: NL;" lang="NL">http://www.cc2e.com/</span></a></span>,<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> Amazon</span><span lang="EN-AU"> </span>rating: 5 sterren.</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;"> </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;">Code Complete was me jaren geleden aangeraden als hét boek (‘de bijbel’) om te leren nette code te produceren. Enige tijd geleden (!) is de tweede editie uitgekomen, wat me een goed moment leek om deze eens te bestuderen. Het viel me gelijk op dat deze dikke pil van Microsoft<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> Press</span> afkomstig is; auteur<span style="mso-ansi-language: EN-AU;"> <span lang="EN-AU">Steve McConnell</span></span><span lang="EN-AU"> </span>komt uit de (Microsoft) wereld van C-programmeurs, maar beheerst vele andere talen.</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;"> </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;">Het boek geeft de lezer diverse praktische, aan de praktijk gestaafde, gedetailleerde tips en voorbeelden om op een juiste manier programmacode te maken. De meeste voorbeelden gaan uit van C++, Visual<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> Basic</span>, Java en C# (in die volgorde). Daar zit ’m wat mij betreft ook meteen een manco: ikzelf ben niet (meer) geïnteresseerd in allerlei tips om onder anderen netjes met pointers en globale variabelen om te gaan. Dat heeft Java netjes voor me afgeschermd… Wel krijg je een interessant kijkje in de keuken van C/C++, en wat extra respect voor programmeurs daarin, die zelfdiscipline nodig hebben, waar wij de taal Java hebben om dezelfde mate van noodzakelijke restrictie te krijgen.</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;"> </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;">De structuur, lay-out en leesbaarheid van het boek is zeer goed: er is op een prettig leesbare manier geschreven, hier en daar humoristisch en nergens flauw. Een uitgebreide inhoudsopgave, lijst van tabellen &amp; figuren, referenties, leeslijst van tijdschriften en boeken, en index ontbreken niet. Elk hoofdstuk begint met een duidelijke inleiding van de inhoud, en eindigt met een checklist, samenvatting van de <span style="mso-ansi-language: EN-AU;" lang="EN-AU">‘key points</span>’ en vele referenties naar extra leesvoer. Dat laatste is erg opvallend:<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> Steve</span> heeft ontzettend veel materiaal gebruikt bij het samenstellen van dit boek. In het voorwoord claimt hij dan ook dat zijn boek een samenvatting is van heel veel (zo niet alle) succesvolle ontwikkelingen en ontdekkingen op het gebied van softwareconstructie. Overal in het boek staan in de kantlijn referenties naar de ‘cc2e’ website met meer informatie, betekenisvolle quotes van bekende IT-goeroes en kruisverwijzingen. Naast verwijzingen naar onderzoeksresultaten van academici, veelal met statistische gegevens, put de auteur ook uit zijn eigen rijke ervaringen bij o.a. Microsoft, Boeing en NASA. Veel stukken code worden begeleid door een “coding horror” icoontje, om aan te geven hoe verschrikkelijk het desbetreffende antivoorbeeld is.</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;"> </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;">Het boek omvat 6 delen, onderverdeeld in 35 hoofdstukken, elk met hun eigen onderwerp. Teveel om allemaal te noemen, maar enkele sappige details &amp; citaten wil ik je niet onthouden:</span></p>
<ul style="margin-top: 0cm;" type="disc">
<li class="MsoNormal" style="margin: 0cm 0cm 0pt; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt;"><span style="font-size: small;"><span style="font-family: Times New Roman;"><em style="mso-bidi-font-style: normal;">“</em><em style="mso-bidi-font-style: normal;"><span style="mso-ansi-language: EN-GB;" lang="EN-GB">Software Construction is the only activity that is guaranteed to be done</span>”</em>: dit is een stevig argument voor Agile werken – waarin documentatie een ondergeschikte rol krijgt toebedeeld ten gunste van productie van programmacode.</span></span></li>
<li class="MsoNormal" style="margin: 0cm 0cm 0pt; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt;"><span style="font-size: small;"><span style="font-family: Times New Roman;"><em style="mso-bidi-font-style: normal;">“</em><em style="mso-bidi-font-style: normal;"><span style="mso-ansi-language: EN-GB;" lang="EN-GB">Program into, not in, a language</span>”</em>: hiermee wil<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> Steve</span> je aanzetten om de mogelijkheden van je taal wijselijk te gebruiken, en niet blind alle mogelijkheden – al dan niet op een verkeerde wijze – toe te passen.</span></span></li>
<li class="MsoNormal" style="margin: 0cm 0cm 0pt; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt;"><span style="font-size: small; font-family: Times New Roman;">De sectie over complexiteit en het beperkte menselijke begripsvermogen is erg vermakelijk.</span></li>
<li class="MsoNormal" style="margin: 0cm 0cm 0pt; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt;"><em style="mso-bidi-font-style: normal;"><span style="mso-ansi-language: EN-GB;" lang="EN-GB"><span style="font-size: small;"><span style="font-family: Times New Roman;">“Don’t optimise your code, unless a profiler or production problem forces you to.”</span></span></span></em></li>
<li class="MsoNormal" style="margin: 0cm 0cm 0pt; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt;"><span style="font-size: small; font-family: Times New Roman;">Als alternatief voor nette UML ontwerpen: neem foto’s van tekeningen op<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> whiteboard</span>, of bewaar flip-overs.</span></li>
<li class="MsoNormal" style="margin: 0cm 0cm 0pt; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt;"><span style="font-size: small; font-family: Times New Roman;">Itereer je design.</span></li>
<li class="MsoNormal" style="margin: 0cm 0cm 0pt; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt;"><span style="font-size: small; font-family: Times New Roman;">Gebruik tijdens ontwikkeling asserts of excepties die je programma hard doen crashen, maar zorg dat in de productieversie dezelfde fout netjes (liefst zonder interactie van, en overlast voor, de gebruiker) wordt afgehandeld. Dit wordt ook wel<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> offensive</span> vs.<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> defensive programming</span> genoemd.</span></li>
<li class="MsoNormal" style="margin: 0cm 0cm 0pt; mso-list: l0 level1 lfo1; tab-stops: list 36.0pt;"><span style="font-size: small; font-family: Times New Roman;">Schrijf alles altijd uit in pseudo-code. Persoonlijk doe ik dit zeer zelden – en ik heb uit dit boek ook geen extra stimulans daarvoor gehaald, onder anderen door het detailniveau dat wordt aangeraden.</span><span style="font-size: small; font-family: Times New Roman;"> </span></li>
</ul>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;">Veel van de onderwerpen die beschreven worden –<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> requirements</span>, design, optimalisatie,<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> naming convention</span>, (unit)<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> testing</span>, Design<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> Patterns</span>, encapsulatie, factorisatie,<span style="mso-ansi-language: EN-AU;" lang="EN-AU"> assert</span> vs. excepties vs. <span style="mso-ansi-language: EN-AU;" lang="EN-AU">unit tests, continuous integration, comments vs. refactoring</span> – waren eerlijk gezegd een samenvatting van wat ik al wist. Nuttig om hier en daar iets nieuws te horen, of om even opgefrist te worden, maar echt iets fundamenteels geleerd: nee.</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;"> </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;">Wat pijnlijk duidelijk wordt, is dat het boek geschreven is vlak voordat Java5 uitkwam – hier en daar wordt Java verweten enkele mogelijkheden te ontberen, terwijl we die al jaren tot onze beschikking hebben.</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;"> </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;">Concluderend: het boek maakt wat mij betreft zijn belofte slechts gedeeltelijk waar. Voor C++/C#/VB programmeurs is het vast en zeker erg bruikbaar, maar voor Java is het net iets te oud, en ligt er te weinig focus op problemen in Java. Als je junior of medior bent, of voor een breed scala aan onderwerpen in software constructie met één boek klaar wilt zijn, is het een <span style="text-decoration: underline;">goed</span> boek, maar helaas geen <span style="text-decoration: underline;">uitstekend</span> boek…</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;"> </span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: small; font-family: Times New Roman;">Kleurindicatie: <strong style="mso-bidi-font-weight: normal;"><span style="color: #ffcc00;">Amber</span></strong> (2 op schaal van 3)</span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: 12pt; font-family: &quot;Times New Roman&quot;; mso-ansi-language: NL; mso-fareast-font-family: 'Times New Roman'; mso-fareast-language: NL; mso-bidi-language: AR-SA;">Hierbij nodig ik al mijn collega’s uit om ook boekbesprekingen te publiceren op de J-Tech blog, en tevens informatie te plaatsen op de Wiki (<a href="https://wiki.ordina.nl/confluence/display/GENBIEB/Alle+Boeken">https://wiki.ordina.nl/confluence/display/GENBIEB/Alle+Boeken</a>), zodat iedereen een goede keus kan maken uit de vele boeken waarmee je je vaardigheden en kennis kunt uitbreiden. Ikzelf hoop binnenkort te komen met een bespreking van “Programming in Scala,” het eerste boek over deze nieuwe en spannende programmeertaal.</span></p>
<p><span style="font-size: 12pt; font-family: &quot;Times New Roman&quot;; mso-ansi-language: NL; mso-fareast-font-family: 'Times New Roman'; mso-fareast-language: NL; mso-bidi-language: AR-SA;">Hedzer Westra</span></p>
<p><span style="font-size: 12pt; font-family: &quot;Times New Roman&quot;; mso-ansi-language: NL; mso-fareast-font-family: 'Times New Roman'; mso-fareast-language: NL; mso-bidi-language: AR-SA;"><a href="http://blog.smart-java.nl/blog/wp-content/uploads/2009/01/hedzerwestra_93x123.jpg"><img class="alignnone size-medium wp-image-284" title="hedzerwestra_93x123" src="http://blog.smart-java.nl/blog/wp-content/uploads/2009/01/hedzerwestra_93x123.jpg" alt="" width="93" height="123" /></a></span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2009/01/21/boekbespreking-code-complete-2nd-edition/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Deadlock debugging tools in Java SE 5 en 6</title>
		<link>http://blog.smart-java.nl/blog/index.php/2008/06/25/deadlock-debugging-tools-in-java-se-5-en-6/</link>
		<comments>http://blog.smart-java.nl/blog/index.php/2008/06/25/deadlock-debugging-tools-in-java-se-5-en-6/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 20:10:18 +0000</pubDate>
		<dc:creator>Jan-Kees van Andel</dc:creator>
				<category><![CDATA[Concurrency]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Tools/Frameworks]]></category>
		<category><![CDATA[deadlocks]]></category>
		<category><![CDATA[explicit lock]]></category>
		<category><![CDATA[intrinsic lock]]></category>
		<category><![CDATA[Java language]]></category>
		<category><![CDATA[Java SE 5]]></category>
		<category><![CDATA[Java SE 6]]></category>
		<category><![CDATA[jstack]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[ReentrantLock]]></category>
		<category><![CDATA[stack]]></category>
		<category><![CDATA[Thread]]></category>
		<category><![CDATA[thread dump]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://blog.smart-java.nl/?p=34</guid>
		<description><![CDATA[Iedereen kent java, javadoc en javac, maar er wordt nog een heel stel tools meegeleverd met de SDK&#8217;s van tegenwoordig.
Denk bijvoorbeeld aan de keytool waarmee je je certificaten en public/private keys beheert. Of apt, waarmee je @compile-time annotations kunt verwerken.
Ook zitten er handige debugging tools bij, zoals:

jps
Geef een lijst van alle Java processen op dit [...]]]></description>
			<content:encoded><![CDATA[<p>Iedereen kent java, javadoc en javac, maar er wordt nog een heel stel tools meegeleverd met de SDK&#8217;s van tegenwoordig.</p>
<p>Denk bijvoorbeeld aan de keytool waarmee je je certificaten en public/private keys beheert. Of apt, waarmee je @compile-time annotations kunt verwerken.</p>
<p>Ook zitten er handige debugging tools bij, zoals:</p>
<ul>
<li><strong>jps</strong><br />
Geef een lijst van alle Java processen op dit systeem.</li>
<li><strong>jconsole</strong><br />
Op JMX gebaseerde GUI om Java applicaties mee te beheren.</li>
<li><strong>jstat</strong><br />
Toon performance gerichte statistieken voor een bepaald Java proces. Er zijn statistieken voor o.a. garbage collection, classloading en permspace.</li>
<li><strong>jinfo</strong><br />
Toon system properties en command line arguments.</li>
<li><strong>jmap</strong><br />
Maak een snapshot van de heap en schrijf die weg naar een file.</li>
<li><strong>jhat (JDK 6)</strong><br />
Genereer op basis van een jmap file een web interface om daarop rapportages uit te voeren. Bevat onder andere een flexibele OQL query tool om specifieke objecten te zoeken. Bijvoorbeeld alle gepoolede EJB Session Beans of strings die aan bepaalde eisen voldoen. Let op: Deze queries kunnen erg lang duren, afhankelijk van de grootte van de heap snapshot. Probeer voor de grap maar eens uit op een Eclipse snapshot.</li>
<li><strong>jstack (Niet in JDK 5 onder Windows en Linux Itanium)</strong><br />
Genereer een stack dump, dus een stack trace voor elke thread.</li>
</ul>
<p>Al deze tools kunnen zowel voor een lokale als een remote JVM (bijvoorbeeld op een testserver) gebruikt worden. Dat maakt ze zeer geschikt voor concurrency issues, aangezien die lokaal vaak niet lastig reproduceren zijn.</p>
<p><strong><em>Let op: Deze tools zijn allemaal experimenteel en worden niet ondersteund. jinfo heeft bijvoorbeeld onder Windows maar beperkte functionaliteit en jstack wordt onder Windows helemaal niet meegeleverd.<br />
</em></strong></p>
<h3>jstack</h3>
<p>Vooral jstack is een handige tool. In JDK 5 was het niet echt bruikbaar, omdat de informatie niet echt overzichtelijk getoond werd. Bovendien was er alleen ondersteuning voor intrinsic locks (synchronized blokken) en niet voor expliciete locks. In JDK 6 wordt veel meer informatie getoond. Laten we bijvoorbeeld onderstaande code eens uitvoeren (vrijwel gegarandeerde deadlock).</p>
<pre class="java">
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class DeadLocker {
	public static void main(String[] args) {
		Lock lock1 = new ReentrantLock();
		Lock lock2 = new ReentrantLock();
		new Thread(new Worker(lock1, lock2), "Worker 1").start();
		new Thread(new Worker(lock2, lock1), "Worker 2").start();
	}
}

class Worker implements Runnable {
	private Lock lock1, lock2;

	public Worker(Lock lock1, Lock lock2) {
		this.lock1 = lock1;
		this.lock2 = lock2;
	}

	public void run() {
		int i = 1;
		for (;;) {
			try {
				lock1.lock();
				try {
					lock2.lock();

					System.out.println("Iteration #" + i++);
				} finally {
					lock2.unlock();
				}
			} finally {
				lock1.unlock();
			}
		}
	}
}
</pre>
<p>Deze code start twee threads met beide een infinite loop. In die loop staan twee geneste lock constructies. Op zicht niet erg, behalve dat beide threads omgekeerd locken. Er is maar een klein beetje ongelukkige CPU scheduling nodig voor een deadlock (in dit voorbeeld vrijwel gegarandeerd door de infinite loop). Als op de plaats van de System.out.println() een dure operatie staat (zoals een DB query) wordt de kans op een deadlock nog groter.</p>
<p>Ik gebruik hier expliciete locks, maar met synchronized is het gedrag hetzelfde.</p>
<p>In dit voorbeeld is de fout nog wel te vinden, maar als dit tig niveau&#8217;s diep in een enterprise applicatie (eventueel gedeployed op een Java EE applicatieserver) gebeurt, wordt je niet gelukkig, want je ziet door de bomen het bos niet meer.</p>
<p>Gelukkig zijn er tools om je te helpen, ook in de standaard JDK.</p>
<p>Als we deze applicatie draaien, blijft het proces hangen (dat is namelijk het probleem van een deadlock). Dat proces zoeken we eerst op met het volgende commando.</p>
<pre class="java">
C:\Users\Jan-Kees>jps
2516 Jps
3908 DeadLocker
</pre>
<p>Zoals je ziet, zijn er verschillende processen actief, waaronder ons DeadLocker proces. Het nummertje ervoor is het proces-id. Dit hebben we nodig voor de volgende stappen.</p>
<p>Dan gaan we met jstack kijken naar een JDK 5 thread dump. Helaas heb ik op deze computer Windows en daardoor geen jstack, maar als je gewoon de applicatie vanaf de command line opstart, kun je met CTRL+BREAK ook een thread dump maken. De output is vergelijkbaar met die van jstack. Dit is de thread dump onder JDK 5.</p>
<pre class="java">
Full thread dump Java HotSpot(TM) 64-Bit Server VM (1.5.0_15-b04 mixed mode):

"DestroyJavaVM" prio=6 tid=0x00000000003ca7b0 nid=0x1274 waiting on condition [0x0000000000000000..0x000000000012f810]

"Worker 2" prio=6 tid=0x0000000005c1c7a0 nid=0x105c waiting on condition [0x000000000686f000..0x000000000686f910]
        at sun.misc.Unsafe.park(Native Method)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:118)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:716)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:746)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1076)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:184)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:256)
        at Worker.run(DeadLocker.java:27)
        at java.lang.Thread.run(Thread.java:595)

"Worker 1" prio=6 tid=0x00000000002da5b0 nid=0xf38 waiting on condition [0x000000000676f000..0x000000000676f990]
        at sun.misc.Unsafe.park(Native Method)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:118)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:716)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:746)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1076)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:184)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:256)
        at Worker.run(DeadLocker.java:27)
        at java.lang.Thread.run(Thread.java:595)

"Low Memory Detector" daemon prio=6 tid=0x0000000005c07a70 nid=0x129c runnable [0x0000000000000000..0x0000000000000000]

"CompilerThread1" daemon prio=10 tid=0x0000000005c073e0 nid=0x1188 waiting on condition [0x0000000000000000..0x000000000646ec60]

"CompilerThread0" daemon prio=10 tid=0x0000000005c05d50 nid=0x109c waiting on condition [0x0000000000000000..0x000000000636e7b0]

"AdapterThread" daemon prio=10 tid=0x0000000005bfffa0 nid=0xb04 waiting on condition [0x0000000000000000..0x0000000000000000]

"Signal Dispatcher" daemon prio=10 tid=0x000000000034ebc0 nid=0xf00 waiting on condition [0x0000000000000000..0x0000000000000000]

"Finalizer" daemon prio=8 tid=0x000000000034f710 nid=0x10c0 in Object.wait() [0x000000000606f000..0x000000000606f990]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000003fec11a8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:120)
        - locked <0x000000003fec11a8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:136)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=10 tid=0x000000000034f180 nid=0xd4c in Object.wait() [0x0000000005f6f000..0x0000000005f6f910]
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000003fec1020> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:474)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
        - locked <0x000000003fec1020> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=10 tid=0x000000000034eaa0 nid=0x7d0 runnable

"GC task thread#0 (ParallelGC)" prio=6 tid=0x00000000003cb7b0 nid=0x318 runnable

"GC task thread#1 (ParallelGC)" prio=6 tid=0x00000000003cb8f0 nid=0x1234 runnable

"VM Periodic Task Thread" prio=10 tid=0x00000000002d9770 nid=0x724 waiting on condition
</pre>
<p>Dit is al leuk. We hebben maar twee threads en twee lock objecten, dus we kunnen het probleem gemakkelijk terugvinden. Bij meer threads (zoals in een applicatieserver) wordt het veel lastiger. Alleen als je ervaring hebt op dit gebied EN je kent de applicatie door en door, dan kun je hier eventueel mee uit de voeten, maar in de meeste gevallen wil je meer informatie hebben. Je hebt namelijk geen zin om al die Object ID’s continu handmatig te moeten vergelijken.</p>
<p>Java 6 biedt meer info, in de vorm van een uitgebreidere jstack. Laten we het programma nog eens een keer opstarten, maar nu onder de nieuwe JDK.</p>
<p>Weer een keertje jps om te zien wat nu het proces-id is.</p>
<pre class="java">
C:\Users\Jan-Kees>jps
4196 DeadLocker
4228 Jps
</pre>
<p>En daarna jstack [proces-id] (met Java 6 wordt wel een jstack voor Windows meegeleverd <img src='http://blog.smart-java.nl/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> )</p>
<pre class="java">
C:\Users\Jan-Kees>jstack 4196
2008-06-25 21:39:05
Full thread dump Java HotSpot(TM) Client VM (10.0-b22 mixed mode, sharing):

"DestroyJavaVM" prio=6 tid=0x00441c00 nid=0x100 waiting on condition [0x00000000..0x001bfd20]
   java.lang.Thread.State: RUNNABLE

"Worker 2" prio=6 tid=0x00491800 nid=0x838 waiting on condition [0x04b2f000..0x04b2fae8]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x2456b800> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:747)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:778)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1114)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:186)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
        at Worker.run(DeadLocker.java:27)
        at java.lang.Thread.run(Thread.java:619)

"Worker 1" prio=6 tid=0x00491000 nid=0x13e0 waiting on condition [0x04a9f000..0x04a9fb68]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x2456b828> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:747)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:778)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1114)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:186)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
        at Worker.run(DeadLocker.java:27)
        at java.lang.Thread.run(Thread.java:619)

"Low Memory Detector" daemon prio=6 tid=0x00483800 nid=0xa40 runnable [0x00000000..0x00000000]
   java.lang.Thread.State: RUNNABLE

"CompilerThread0" daemon prio=10 tid=0x00477400 nid=0x76c waiting on condition [0x00000000..0x048ef914]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" daemon prio=10 tid=0x00474c00 nid=0xf94 runnable [0x00000000..0x00000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x0046bc00 nid=0x12b0 runnable [0x00000000..0x00000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=8 tid=0x00462800 nid=0x12d0 in Object.wait() [0x0473f000..0x0473fa68]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x24540b28> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
        - locked <0x24540b28> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=10 tid=0x00461800 nid=0x5fc in Object.wait() [0x046af000..0x046afae8]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x24540a30> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:485)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
        - locked <0x24540a30> (a java.lang.ref.Reference$Lock)

"VM Thread" prio=10 tid=0x00460400 nid=0x1378 runnable

"VM Periodic Task Thread" prio=10 tid=0x00485000 nid=0x13dc waiting on condition

JNI global references: 604

Found one Java-level deadlock:
=============================
"Worker 2":
  waiting for ownable synchronizer 0x2456b800, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
  which is held by "Worker 1"
"Worker 1":
  waiting for ownable synchronizer 0x2456b828, (a java.util.concurrent.locks.ReentrantLock$NonfairSync),
  which is held by "Worker 2"

Java stack information for the threads listed above:
===================================================
"Worker 2":
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x2456b800> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:747)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:778)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1114)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:186)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
        at Worker.run(DeadLocker.java:27)
        at java.lang.Thread.run(Thread.java:619)
"Worker 1":
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x2456b828> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInt
errupt(AbstractQueuedSynchronizer.java:747)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:778)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1114)
        at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:186)
        at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
        at Worker.run(DeadLocker.java:27)
        at java.lang.Thread.run(Thread.java:619)

Found 1 deadlock.
</pre>
<p>Als je naar het laatste stuk kijkt, zie je dat er nu meer informatie getoond wordt. Hij geeft duidelijk aan dat hij een deadlock ontdekt heeft, namelijk tussen de threads &#8220;Worker 2&#8243; en &#8220;Worker 1&#8243;. Je kunt zien dat &#8220;Worker 2&#8243; op lock <0x2456b800> wacht (die in bezit is van &#8220;Worker 1&#8243;). Tegelijk wacht &#8220;Worker 1&#8243; op <0x2456b828> (die in het bezit is van &#8220;Worker 2&#8243;).</p>
<p><strong><em>Tip: Het is slim om af en toe eens een thread dump te maken van een draaiende applicatie, zelfs al is er op dat moment geen deadlock. Het geeft namelijk veel inzicht in het locking gedrag van je applicatie.<br />
</em></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.smart-java.nl/blog/index.php/2008/06/25/deadlock-debugging-tools-in-java-se-5-en-6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
