<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.2" -->
<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/"
	>

<channel>
	<title>Dave Landers</title>
	<link>http://dave.srednal.com</link>
	<description>Dave's thoughts (such as they are)</description>
	<pubDate>Tue, 12 Aug 2008 15:41:01 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.2</generator>
	<language>en</language>
			<item>
		<title>Time Machine Restore works</title>
		<link>http://dave.srednal.com/archives/35</link>
		<comments>http://dave.srednal.com/archives/35#comments</comments>
		<pubDate>Tue, 18 Mar 2008 18:11:47 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://dave.srednal.com/archives/35</guid>
		<description><![CDATA[I just got a new MacBook Pro yesterday.  I &#8220;needed&#8221; a new machine because my old one is a Core Duo (not Core 2 Duo) and wouldn&#8217;t run the Java 6 preview.  And my son &#8220;needed&#8221; my old MacBook Pro for college.  Yea, that&#8217;s it.
Anyway, I turned on the new machine this [...]]]></description>
			<content:encoded><![CDATA[<p>I just got a new MacBook Pro yesterday.  I &#8220;needed&#8221; a new machine because my old one is a Core Duo (not Core 2 Duo) and wouldn&#8217;t run the Java 6 preview.  And my son &#8220;needed&#8221; my old MacBook Pro for college.  Yea, that&#8217;s it.</p>
<p>Anyway, I turned on the new machine this morning, and selected the Restore from Time Machine option.  It chugged away for an hour or whatever, but by about 9:30 AM I was sitting in front of a near replica of the other machine.  Pretty cool.</p>
<p>I did have to install XCode and Dashcode again.</p>
<p>And I had to re-acquaint my bluetooth phone with the new Mac.  And re-authorize my iTunes music.</p>
<p>And for some reason, I had to reset my USB drive as the Time Machine volume (and it choose a new backup database folder, so it&#8217;s going to start over with a full backup).</p>
<p><!-- technorati tags start -->
<p style="text-align:right;font-size:10px;">Technorati Tags: <a href="http://www.technorati.com/tag/apple" rel="tag">apple</a>, <a href="http://www.technorati.com/tag/leopard" rel="tag">leopard</a>, <a href="http://www.technorati.com/tag/mac" rel="tag">mac</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://dave.srednal.com/archives/35/feed</wfw:commentRss>
		</item>
		<item>
		<title>MacBook Pro Fixed!</title>
		<link>http://dave.srednal.com/archives/34</link>
		<comments>http://dave.srednal.com/archives/34#comments</comments>
		<pubDate>Wed, 02 Jan 2008 18:04:07 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://dave.srednal.com/archives/34</guid>
		<description><![CDATA[As I reported earlier, I had a severe problem with Time Machine on my MacBook Pro.  As I experimented with it, I realized it was probably related to another problem I have been living with ever since I got the machine.
The previous problem occurred when I was running a build or other long, CPU-intensive [...]]]></description>
			<content:encoded><![CDATA[<p>As I <a href="http://dave.srednal.com/archives/22">reported earlier</a>, I had a severe problem with Time Machine on my MacBook Pro.  As I experimented with it, I realized it was probably related to another problem I have been living with ever since I got the machine.</p>
<p>The previous problem occurred when I was running a build or other long, CPU-intensive operation.  Sometimes, the machine would just reboot suddenly.  And it was always when I was away.  I had no luck with any of the usual fixes suggested by Apple or found on the web.  I had figured out that it was probably related to the screen saver coming on, but it was impossible to reproduce this for anyone.</p>
<p>But something about Time Machine allowed me to reproduce this more repeatably: lots of CPU, generating lots of heat, coupled with intense graphics == reboot.</p>
<p>The folks at the <a href="http://www.apple.com/retail/flatironcrossing" title="Apple Store - FlatIron Crossing">FlatIrons Apple Store</a> were really great, especially given the madhouse produced by the holidays.  I described both problems and they just decided to replace the logic board.  They ordered the part, and I was without my machine for only a day-and-a-half.  It seems like this has done the trick.  Hurray!</p>
<p><!-- technorati tags start -->
<p style="text-align:right;font-size:10px;">Technorati Tags: <a href="http://www.technorati.com/tag/apple" rel="tag">apple</a>, <a href="http://www.technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://www.technorati.com/tag/reboot" rel="tag">reboot</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://dave.srednal.com/archives/34/feed</wfw:commentRss>
		</item>
		<item>
		<title>Paul is an Eagle!</title>
		<link>http://dave.srednal.com/archives/33</link>
		<comments>http://dave.srednal.com/archives/33#comments</comments>
		<pubDate>Fri, 21 Dec 2007 17:08:21 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<category><![CDATA[Scouting]]></category>

		<guid isPermaLink="false">http://dave.srednal.com/archives/33</guid>
		<description><![CDATA[ My oldest son, Paul, had his Board of Review last night, and is now an Eagle Scout.  I am so proud of him, obviously.
After the board was finished with their deliberations, they took a moment for each member to share some of their observations about Paul.  And his mom and I were [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://dave.srednal.com/blog/wp-content/uploads/2007/12/eagle-scout-medal-color.png" height="120" width="72" border="1" align="left" hspace="4" vspace="4" alt="Eagle Scout Medal" title="Eagle Scout Medal" /> My oldest son, Paul, had his Board of Review last night, and is now an <a href="http://www.scouting.org/factsheets/02-516.html">Eagle Scout</a>.  I am so proud of him, obviously.<br />
After the board was finished with their deliberations, they took a moment for each member to share some of their observations about Paul.  And his mom and I were invited in to hear these.  The board was several adults, most of whom did not know each other, but all knew Paul from various places - school, church, scouting.  It was great to hear all the positive observations they shared about Paul.  And equally great to hear a consensus that he is the same kind of person in all these different environments.</p>
<p>The comments last night made it clear what we already knew about Paul:  while he did work hard to meet all the Eagle requirements, he did not have to work to become the kind of person you expect an Eagle to be.  He just is that kind of person.<br />
He worked hard for this, obviously, but all that work served only to validate who he already was.</p>
<p>Congratulations, Paul!<br />
<!-- technorati tags start -->
<p style="text-align:right;font-size:10px;">Technorati Tags: <a href="http://www.technorati.com/tag/eagle" rel="tag">eagle</a>, <a href="http://www.technorati.com/tag/bsa" rel="tag">bsa</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://dave.srednal.com/archives/33/feed</wfw:commentRss>
		</item>
		<item>
		<title>CSS Overflow Scrollbars and IE</title>
		<link>http://dave.srednal.com/archives/31</link>
		<comments>http://dave.srednal.com/archives/31#comments</comments>
		<pubDate>Mon, 17 Dec 2007 22:12:25 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://dave.srednal.com/archives/31</guid>
		<description><![CDATA[Someone pointed out to me that some of my code sections were unreadable in Internet Explorer.  They looked like this:

Hey! where&#8217;s the text?  The rest of us (at least Firefox and Safari) were seeing something more like this:

Much better, but what&#8217;s going on?
I quote code in a &#60;pre class="code"&#62;....&#60;/pre&#62; block.  And my [...]]]></description>
			<content:encoded><![CDATA[<p>Someone pointed out to me that some of my code sections were unreadable in Internet Explorer.  They looked like this:</p>
<p><img src="http://dave.srednal.com/blog/wp-content/uploads/2007/12/pre-code-ie.png" height="76" width="453" border="1" hspace="4" vspace="4" alt="IE view of my code" title="IE view of my code" /></p>
<p>Hey! where&#8217;s the text?  The rest of us (at least Firefox and Safari) were seeing something more like this:</p>
<p><img src="http://dave.srednal.com/blog/wp-content/uploads/2007/12/pre-code-safari.png" height="90" width="451" border="1" hspace="4" vspace="4" alt="Safari view of my code" title="Safari view of my code" /></p>
<p>Much better, but what&#8217;s going on?</p>
<p>I quote code in a <code>&lt;pre class="code"&gt;....&lt;/pre&gt;</code> block.  And my style sheet contained:</p>
<pre class="code">.code {
    font-family: courier, monospace;
    margin: 10px 20px;
    padding: 3px 8px;
    border: 1px dashed #999999;
    overflow:auto;
}
</pre>
<p>It looked to me like IE was robbing space from either the text height or the padding to cram in a scrollbar.  And since that made the resulting area for text too small, it also added a (way too small) vertical scrollbar, too.  The result is non-functional in any real sense.</p>
<p>A bit of searching and I am drawn to this comment from the <a href="http://www.w3.org/TR/2006/WD-CSS21-20060411/visufx.html#propdef-overflow">CSS 2.1 spec</a>:</p>
<blockquote><p>In the case of a scrollbar being placed on an edge of the element&#8217;s box, it should be inserted between the inner border edge and the outer padding edge. Any space taken up by the scrollbars should be subtracted from the computed width/height, thus preserving the inner border edge.</p></blockquote>
<p>As I read this, the scrollbar needs to fit inside the element border, and thus subtracts from space that can be used for the content.  This does preserve the overall size of the element no matter what type of scrolling might be used (or not).  But in my context, it seems wrong.  It also means that IE is probably right here (which also goes against my intuition :).</p>
<p>Wrong or not, it is certainly not what I want.  So I did more hunting and experimenting, and I found only two solutions that I really thought worked.</p>
<p>First, I could simply increase the padding-bottom to make room for the scrollbar.  This solution is nice because it keeps the browser-specific hacks out of the stylesheet.  But I don&#8217;t like the way this looks when there is not a scrollbar, because there&#8217;s extra blank padding at the bottom.</p>
<p>So the only real choice for me was to add some browser-specific thing to the stylesheet.  What I ended up with is based mainly on<br />
<a href="http://browservulsel.blogspot.com/2005/04/ie-overflow-auto-scrollbar-overlap.html" title="Browservulsel: IE overflow auto scrollbar overlap">this post</a>, and looks like this:</p>
<pre class="code">.code {
    font-family: courier, monospace;
    margin: 10px 20px;
    padding: 3px 8px;
    border: 1px dashed #999999;
    overflow:auto;
    /* add padding in IE (which supports expressions) to make room for the scroll bar */
    padding-bottom: expression(this.scrollWidth &gt; this.offsetWidth ? "19px" : "3px");
}</pre>
<p>This seems to be working reasonably well, as it does not mangle the size of the element when there is no need for a scrollbar, and it bumps up the bottom padding to make way for IE&#8217;s scrollbar.</p>
<p>There are some downsides, like the expression is probably <a href="http://developer.yahoo.net/blog/archives/2007/07/high_performanc_6.html" title="High Performance Web Sites: Rule 7 – Avoid CSS Expressions (Yahoo! Developer Network blog)">being over-evaluated</a>, and it relies on a proprietary IE feature (<a href="http://msdn2.microsoft.com/en-us/library/ms537634.aspx" title="About Dynamic Properties">expressions</a>), so I may reevaluate this in the future.  But for now at least my blog is (more) readable for IE users.</p>
<p><!-- technorati tags start -->
<p style="text-align:right;font-size:10px;">Technorati Tags: <a href="http://www.technorati.com/tag/css" rel="tag">css</a>, <a href="http://www.technorati.com/tag/ie" rel="tag">ie</a>, <a href="http://www.technorati.com/tag/scrollbar" rel="tag">scrollbar</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://dave.srednal.com/archives/31/feed</wfw:commentRss>
		</item>
		<item>
		<title>Time Machine Woes</title>
		<link>http://dave.srednal.com/archives/22</link>
		<comments>http://dave.srednal.com/archives/22#comments</comments>
		<pubDate>Thu, 13 Dec 2007 22:18:00 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://dave.srednal.com/archives/22</guid>
		<description><![CDATA[
Yesterday, I decided it was time to move on.  I deleted my bootable Tiger backup and turned on Time Machine.  I like the fact that it promises to do hourly/daily/weekly incremental backups, and the Time Machine application, while heavy on the cheese, is a pretty nice way to access backup recovery.
But backups aren&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://dave.srednal.com/blog/wp-content/uploads/2007/12/timemach.png" height="64" width="64" border="1" align="left" hspace="4" vspace="4" alt="Time Machine" title="Time Machine" /><br />
Yesterday, I decided it was time to move on.  I deleted my bootable Tiger backup and turned on Time Machine.  I like the fact that it promises to do hourly/daily/weekly incremental backups, and the Time Machine application, while heavy on the cheese, is a pretty nice way to access backup recovery.</p>
<p>But backups aren&#8217;t backups unless you test that you can recover files (and you know how to do it without having to mess around when the time comes).  So today, with a day&#8217;s worth of backup history, I decided to play with Time Machine.</p>
<p>I flipped back and forth thru time-cheese, and after a few seconds the world disappeared.  Oh wait, it was just my MacBook Pro rebooting.  Bong.  Apple.  Spin wheel.  Login.</p>
<p>Nothing in any of the logs (there wasn&#8217;t time) - just a hard, fast, shutdown.</p>
<p>So, I did what any self-respecting software engineer would do.  I tried it again.  Same result.  I have now hard-rebooted my machine like 10 times via Time Machine (I don&#8217;t recommend it).</p>
<p>If recovering a file risks a hard shutdown, and I can&#8217;t resolve this - I will just have to go back to rsync.</p>
<p><!-- technorati tags start -->
<p style="text-align:right;font-size:10px;">Technorati Tags: <a href="http://www.technorati.com/tag/apple" rel="tag">apple</a>, <a href="http://www.technorati.com/tag/leopard" rel="tag">leopard</a>, <a href="http://www.technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://www.technorati.com/tag/reboot" rel="tag">reboot</a>, <a href="http://www.technorati.com/tag/time machine" rel="tag">time machine</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://dave.srednal.com/archives/22/feed</wfw:commentRss>
		</item>
		<item>
		<title>Leopard impressions</title>
		<link>http://dave.srednal.com/archives/20</link>
		<comments>http://dave.srednal.com/archives/20#comments</comments>
		<pubDate>Wed, 12 Dec 2007 16:31:09 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://dave.srednal.com/archives/20</guid>
		<description><![CDATA[I&#8217;ve had Leopard installed for several days now, and mostly it is good.  Here are some delights and gripes and bugs and other thoughts.
Mail
Mail still doesn&#8217;t obey the Hide checkbox when it is started at login.  Just what is so hard about this?  I find this really annoying.  My son did [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had Leopard installed for several days now, and mostly it is good.  Here are some delights and gripes and bugs and other thoughts.</p>
<p><strong>Mail</strong></p>
<p>Mail still doesn&#8217;t obey the Hide checkbox when it is started at login.  Just what is so hard about this?  I find this really annoying.  My son did figure out a rather clever  &#8220;cheat&#8221; - he starts Mail in a different Space, so it is not really hidden, but just looks that way (but I&#8217;m not using Spaces).</p>
<p>And Mail still doesn&#8217;t grok the age-old function &#8220;go to next <em>unread</em> message&#8221; (the shortcut for this should be &#8220;spacebar&#8221;).</p>
<p>On the plus side, Mail will finally display a proper count of unread messages in the Dock icon (rather than only counting messages in the inbox).</p>
<p><a href="http://dave.srednal.com/blog/wp-content/uploads/2007/12/mailbug.png" onclick="window.open('http://dave.srednal.com/blog/wp-content/uploads/2007/12/mailbug.png','popup','width=582,height=410,scrollbars=no,resizable=yes,toolbar=no,directories=no,location=no,menubar=no,status=yes,left=0,top=0');return false"><img src="http://dave.srednal.com/blog/wp-content/uploads/2007/12/mailbug-tm.jpg" height="100" width="141" border="1" align="right" hspace="4" vspace="4" alt="Mail Bug" /></a>And in the bug arena, there is something seriously wrong.  I occasionally see a popup from Mail saying it can&#8217;t identify the certificate for pop.gmail.com.</p>
<p>When I inspect the certificate, it is the one for my work email account.  So something is seriously broken in Mail&#8217;s multiple-account settings or fetching.</p>
<p><strong>Mail / RSS</strong></p>
<p>I never really have got along with RSS in the browser - never seemed right to me.  So I thought having it in Mail was a good idea - it&#8217;s really where I&#8217;ve wanted most of my feeds all along.  But Apple&#8217;s implementation is just not &#8220;there&#8221; yet. It would probably work for someone with just a handful of feeds, but not for me.</p>
<p>First, there is just no way to import a set of feeds from anywhere but Safari.  I found <a href="http://theappleblog.com/2007/11/08/how-to-import-rss-subscriptions-into-apple-mail/" title="How To: Import RSS Subscriptions into Apple Mail - The Apple Blog">these instructions</a> and got my OPML feeds imported (via Firefox to Safari to Mail - ugh), but they lost their folders. It took me a while to figure out that you can create folders for feeds (you just create a new mailbox), and then I was on the way to rebuilding my folders, and importing feeds into them.  But along the way I figured out that you can&#8217;t sort or arrange anything.  So I was stuck thinking I&#8217;d have to rename my folders so they&#8217;d be &#8220;aNews&#8221;, &#8220;bTech&#8221;, &#8220;cBlogs&#8221;, etc.  Gack.  And things were just getting crowded in the sidebar - what with my inboxes and all my mail folders, there just wasn&#8217;t room for a dozen more folders for feeds.</p>
<p>So I came to my senses and went back to using the most excellent <a href="http://www.newsgator.com/Individuals/NetNewsWire/" title="RSS Reader for Mac - NetNewsWire">NetNewsWire</a>.</p>
<p><strong>Safari</strong></p>
<p>I think the best thing in the new Safari is actually the new eye candy in the Find feature.  I was always having trouble seeing the default (subtile) blue highlight.  Apple has now made it easy to see the find results on any web page (regardless of color scheme).</p>
<p>The history menu also now has two new options:  Reopen Last Closed Window and Reopen All Windows from Last Session.  Fantastic for those of us who sometimes accidentally close or quit.</p>
<p>The other two things I like come with the <a href="http://developer.apple.com/internet/safari/faq.html#anchor14" title="Safari Developer FAQ">debug menu</a>.  First, they moved Open Page With and User Agent from the bottom to the top of the menu.  And the new Web Inspector is great (kinda like Firebug, but more Apple-y).  I especially like the way it rolls up CSS styles and shows Metrics (margins/borders/padding/size).</p>
<p><strong>Spotlight</strong></p>
<p>Spotlight just seems to work better.  First, there&#8217;s new stuff contributing - most notibly Web History.  Spotlight searches now include your Safari cache, so you can find that site you visited last week.</p>
<p>Also, they&#8217;ve made the &#8220;Top Hit&#8221; automatically selected (rather than messing around with the Command key).  I can type, for example, C-Space, sys, Return and get System Preferences.  It&#8217;s just better.</p>
<p><strong>iCal</strong></p>
<p>Well, finally you can set a default alarm for new events, although there&#8217;s no way that I can see to set the default sound to anything but Basso.  And the default alarm doesn&#8217;t seem to apply to notifications created from Mail.  So some progress here, but still a way to go.</p>
<p><strong>Stacks</strong></p>
<p>I actually like this.  I used to keep folders in my Dock for Applications and Downloads, but this just works better.  I don&#8217;t really like the Fan view, but since my Dock is on the side, all I and use is Grid anyway.</p>
<p><strong>Quick Look</strong></p>
<p>This is going to be really handy, especially now that I&#8217;m starting to learn the shortcut (Command-Y).  It&#8217;s way faster than launching an app just to see what&#8217;s in the file.  Next, I&#8217;m going to have to try a <a href="http://code.google.com/p/qlcolorcode/" title="qlcolorcode - Google Code">code syntax highlighter</a>.</p>
<p><strong>Random Issues</strong></p>
<p>I have my desktop background set to display photos from a folder.  Sometimes, first thing in the morning, my second monitor comes up with the default Leopard background.  If I bring up preferences, it does <em>think</em> that it&#8217;s displaying the photos.  If I wait a half-hour (when the photo is scheduled to change), it gets with the program.</p>
<p>I have noticed that the login dialog doesn&#8217;t get focus when I wake from sleep.  So I type my password and nothing happens till I click in the login dialog.  The worst part is that I sometimes have found bits (or all) of my password sitting in other dialogs or documents - which means those dialogs actually had keyboard focus while they were supposed to be locked out.  Scary.</p>
<p>I am disappointed that WiFi with WPA is still not right.  I have never been able to hold a connection to our work WAN for more than about 15 minutes (it had steadily grown from 5 to about 15 over several Tiger updates).  Now, it seems we&#8217;re back to 5 minutes.  My home network (Linksys) is not as bad as at work, but it does drop connections occasionally, too.  I have no data, but it does seem worse than with the last update of Tiger.  I never had these problems with my PowerBook.</p>
<p><!-- technorati tags start -->
<p style="text-align: right; font-size: 10px">Technorati Tags: <a href="http://www.technorati.com/tag/apple" rel="tag">apple</a>, <a href="http://www.technorati.com/tag/leopard" rel="tag">leopard</a>, <a href="http://www.technorati.com/tag/mac" rel="tag">mac</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://dave.srednal.com/archives/20/feed</wfw:commentRss>
		</item>
		<item>
		<title>Leak Testing</title>
		<link>http://dave.srednal.com/archives/17</link>
		<comments>http://dave.srednal.com/archives/17#comments</comments>
		<pubDate>Tue, 11 Dec 2007 19:15:20 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://dave.srednal.com/archives/17</guid>
		<description><![CDATA[So, here we are.  We have found lots of memory leaks, and drastically improved the redeploy experience for WLP 10.2 (and the fixes are being backported to previous releases).
However, this is not the first time we&#8217;ve been here.  But it is hopefully the last.
We are putting in place a test environment to keep [...]]]></description>
			<content:encoded><![CDATA[<p>So, here we are.  We have found lots of memory leaks, and drastically improved the redeploy experience for WLP 10.2 (and the fixes are being backported to previous releases).</p>
<p>However, this is not the first time we&#8217;ve been here.  But it is hopefully the last.</p>
<p>We are putting in place a test environment to keep these leaks plugged.  Actually, to be more precise, we&#8217;re adding some instrumentation to our integration test suite that drives tests via the IDE.  So this test will behave just like a developer - although it&#8217;s a rather anti-social and uninteresting developer :).</p>
<p>Note that this technique is not restricted to WLP or redeployment testing, but hopefully you can find it useful for other situations.</p>
<p><strong>Counting ClassLoader Instances<br />
</strong><br />
The basis of this technique is that we know that the leaks we are interested in happen to always hold on to the application or webapp ClassLoader.  Further, we also know that these ClassLoaders are instances of GenericClassLoader (for the app) or ChangeAwareClassLoader (for the webapp).</p>
<p>So, our instrumentation relies on being able to count the instances of these classes.  Fortunately, JRockit can do this easily, without any extra messing about with the startup settings or whatnot.</p>
<p><a href="http://edocs.bea.com/jrockit/webdocs/index.html" title="JRockit documentation">JRockit</a> comes with this handy <a href="http://edocs.bea.com/jrockit/geninfo/diagnos/ctrlbreakhndlr.html#wp1000350" title="jrcmd documentation">jrcmd</a> command.  It lets you interact with a running JRockit JVM, like for example the WLS server.  You can use it to do all sorts of interesting things:</p>
<ul>
<li>find out the JVM&#8217;s command line (how it was started)</li>
<li>print thread dumps</li>
<li>change the verbosity of the JVM on the fly (things like garbage collector stats)</li>
<li>trigger a garbage collection</li>
<li>print a GC report</li>
<li>print diagnostics about memory usage</li>
</ul>
<p>All sorts of cool things - and none of these require you to change anything about your running process.  No command line switches or anything messy like that.</p>
<p>So, we are looking for a count of the instances of our ClassLoader objects.  We do that by running:</p>
<pre class="code">jrcmd &lt;wls server pid&gt; heap_diagnostics
</pre>
<p>(You get the wls server pid by running just <code>jrcmd</code> - it will print the process ids of running JRockit instances.)</p>
<p>If you run that, you&#8217;ll see tons and tons of output - including a listing of every class loaded by the system and how many instances there are.  So all we need to do is search for the class we are interested in:</p>
<pre class="code">jrcmd &lt;wls server pid&gt; heap_diagnostics | grep '%.*GenericClassLoader
</pre>
<p>That will grep for the one line we are interested in (turns out it contains a percent sign; why is not important here).  We&#8217;ll get output something like this:</p>
<pre class="code">     0.0% 10k      150    +10k weblogic/utils/classloaders/GenericClassLoader
</pre>
<p>In the above, we see that there are 150 instances of the GenericClassLoader.</p>
<p>To get a more accurate count, we also want to trigger a full garbage collection and finalization before counting anything.  We can do that with jrcmd also:</p>
<pre class="code">jrcmd &lt;wls server pid&gt; runfinalization
</pre>
<p>Using this information, here&#8217;s what we are doing for WLP testing:</p>
<ol>
<li>Start the server, with the application undeployed.</li>
<li>Run finalization and count the GenericClassLoader and ChangeAwareClassLoader instances.  This gives us a baseline for the number of instances used by the server itself.</li>
<li>Deploy the application and use it (i.e. wander through the portal in a browser)</li>
<li>Count instances again.</li>
<li>Redeploy the application, use it, and recount.</li>
<li>Repeat the redeploy step several times.</li>
<li>Undeploy the application.</li>
<li>Count instances.</li>
</ol>
<p>All these counts (and additionally the [re-]deploy times) are all being recorded and analyzed.  The most important metric is that the first and last counts are the same - after the application is undeployed, the ClassLoaders used by the application should be gone.  We are collecting the intermediate results because we expect they might be useful in failure analysis.</p>
<p>The one last step is that we are running the JVM instrumented for YourKit, and configured to dump a memory snapshot on exit.  So if the ClassLoader counts don&#8217;t look right, a developer will have the memory snapshot for analysis, without having to rerun the whole test suite.</p>
<p>Hopefully some of this information can be useful if you have leaks you are hunting.<br />
<!-- technorati tags start -->
<p style="text-align:right;font-size:10px;">Technorati Tags: <a href="http://www.technorati.com/tag/JRockit" rel="tag">JRockit</a>, <a href="http://www.technorati.com/tag/leak" rel="tag">leak</a>, <a href="http://www.technorati.com/tag/memory" rel="tag">memory</a>, <a href="http://www.technorati.com/tag/portal" rel="tag">portal</a>, <a href="http://www.technorati.com/tag/YourKit" rel="tag">YourKit</a>, <a href="http://www.technorati.com/tag/WebLogic" rel="tag">WebLogic</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://dave.srednal.com/archives/17/feed</wfw:commentRss>
		</item>
		<item>
		<title>Leopard Install Notes</title>
		<link>http://dave.srednal.com/archives/16</link>
		<comments>http://dave.srednal.com/archives/16#comments</comments>
		<pubDate>Fri, 07 Dec 2007 16:19:54 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
		<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://dave.srednal.com/archives/16</guid>
		<description><![CDATA[I finally got around to upgrading my MacBook Pro to Leopard.
I generally take the opportunity of an OS upgrade to clean house, and I did it this time with Leopard again.  So I made good backups, then did a clean install (not an upgrade).  I then spend a few days figuring out exactly [...]]]></description>
			<content:encoded><![CDATA[<p>I finally got around to upgrading my MacBook Pro to Leopard.</p>
<p>I generally take the opportunity of an OS upgrade to clean house, and I did it this time with Leopard again.  So I made good backups, then did a clean install (not an upgrade).  I then spend a few days figuring out exactly what I need from the backups and moving that over.  This has several side-effects that I like.  It cleans out the junk: old applications, prefs from apps I tried but no longer use, etc.  It also gives me a fresh look at the new features, since they are not hidden by my old prefs or hacks.</p>
<p><strong>Backups First</strong></p>
<p>The first step is the backups.  I have been using a script (fired from a calendar item) for a while now to backup (via rsync) some critical pieces of my home directory to the Linux box in my office.  But that just wasn&#8217;t going to cut it for an OS upgrade.  I wanted a full, bootable backup of the entire machine.</p>
<p>I got a USB drive and formatted it the same as my main drive (Mac OS Extended Journaled).Then, open Get Info on the drive and uncheck the Ignore Ownership on this drive (at the bottom).Then, use rsync to do a full backup.  This will take quite a while, and works best if you close everything (ilke Mail, etc) first.</p>
<pre class="code"># turn off spotlight first
sudo mdutil -i off /Volumes/BackupDrive
# backup everything
sudo rsync --one-file-system --recursive --links --perms --times --group --owner --extended-attributes --verbose --progress --delete / /Volumes/BackupDrive
# turn off spotlight again, since we just dropped new index files over there
sudo mdutil -i off /Volumes/BackupDrive</pre>
<p>I&#8217;m not sure how necessary the spotlight thing is, but I didn&#8217;t like all the backup versions of apps and stuff showing up in Spotlight searches.</p>
<p>Next, you need to make the drive bootable:</p>
<pre class="code">sudo bless --folder /Volumes/BackupDrive/System/Library/CoreServices</pre>
<p>Great - now for the part that most people skip:  Test the backup!  I shut down the machine, then rebooted holding the Option key.  I booted with the USB drive, and checked that everything looked OK.  So now I know that if something goes drastically wrong with the upgrade, I can at least get some work done.</p>
<p><strong>Planning</strong></p>
<p>The next step, since I was doing a clean install, was to make a few notes.  I scratched out a list of the files I needed, another list of apps and settings that I used every day, and another list of apps, settings, and other things that I wasn&#8217;t sure about.  Then I spent a few minutes making sure I had links to installers, notes containing license keys, etc.</p>
<p>I also exported backups of things like Address Book, iCal, Safari bookmarks, Mail, and Keychain.</p>
<p><strong>Install</strong></p>
<p>I only encountered one hiccup in my plan.  I knew I was going to do a full new install, but I also plan to do an upgrade or archive install at home (to preserve the sanity of my wife and kids).  So I was going to try these first on my laptop, then blow everything away and do my clean install.</p>
<p>So I waited forever for the install DVD to verify (don&#8217;t need to do that again, thankfully), then proceeded with an upgrade install.  But the progress bar was telling me it would take around 4 hours.  I didn&#8217;t have 4 hours to blow on this experiment, so I bailed out and just went straight to the clean install.</p>
<p><strong>ReCreate</strong></p>
<p>The recreation of my &#8220;stuff&#8221; went pretty smoothly.  I went through my checklist and started copying files, apps, and settings.  I did this one at a time, just to keep things clean.  For Mail, I did migrate over my old mail forders, accounts, and preferences - but then made sure to go check out the new prefs to see what&#8217;s new and what I might want to change.</p>
<p>Right away, I got Mail, Adium, iCal, NetNewsWire and Eclipse set up.  Couldn&#8217;t wait on those.  But other apps are being moved over on a slower pace.  I don&#8217;t want them just because I used to use them - I want to make sure I really need them.</p>
<p><strong>Impressions</strong></p>
<p>Things seem a bit faster.  I&#8217;m not sure if it&#8217;s just that I have not (yet) bogged the thing down with hacks, or if Leopard is actually a bit zippier.  Or maybe it&#8217;s the new eye-candy acting as a sort of endorphin or whatever.</p>
<p>I&#8217;ll blog other impressions of new feature &#8220;likes and gripes&#8221; later.</p>
<p><!-- technorati tags start -->
<p style="text-align: right; font-size: 10px">Technorati Tags: <a href="http://www.technorati.com/tag/apple" rel="tag">apple</a>, <a href="http://www.technorati.com/tag/leopard" rel="tag">leopard</a>, <a href="http://www.technorati.com/tag/mac" rel="tag">mac</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://dave.srednal.com/archives/16/feed</wfw:commentRss>
		</item>
		<item>
		<title>Leaks We Plugged</title>
		<link>http://dave.srednal.com/archives/15</link>
		<comments>http://dave.srednal.com/archives/15#comments</comments>
		<pubDate>Fri, 07 Dec 2007 15:19:39 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://dave.srednal.com/archives/15</guid>
		<description><![CDATA[In this post is a dump of most of the leaks that we have found and plugged for our upcoming 10.2 release.  I present it here not so you can see exactly what was leaking or whatever, but rather to give me a format where I can make some notes about what we encountered, [...]]]></description>
			<content:encoded><![CDATA[<p>In this post is a dump of most of the leaks that we have found and plugged for our upcoming 10.2 release.  I present it here not so you can see exactly what was leaking or whatever, but rather to give me a format where I can make some notes about what we encountered, and how we fixed things.  Hopefully, that might prove useful to someone.</p>
<p>Note that many of these leaks were never released, but were only present in internal revisions.  But the ones that did make it out are being back-ported to patches for 10.0 and 9.2.</p>
<p>I&#8217;ve also kind-of-categorized them into a few groupings, where similar patterns have emerged.  Some did not fit clearly into just one category, but the breakdown should help other leak-hunters in their quests.</p>
<p><strong>Clean Up After Yourself!</strong></p>
<p>This class of problems is caused by creating references to objects without clearing them when you are done with them.  The <a href="http://dave.srednal.com/archives/13" title="Leak Patterns: new Thread">Thread</a> and <a href="http://dave.srednal.com/archives/14" title="LeakPatterns: ThreadLocal">ThreadLocal</a> issues I discussed in earlier posts generally fall under this category.</p>
<p><strong>Timers not released:</strong>  If an app created a Timer (via <code>commonj.timers.TimerManager</code>), and the timer did not stop before the application undeployed, it was not cleaned up (and thus leaked).  The culprit was a misused <code>WeakHashMap</code>.  The Timers were stored like this:</p>
<pre class="code">WeakHashMap timers = new WeakHashMap();
...
timers.put(theTimer, theTimer);
</pre>
<p>The map was just being used as a Set, but the insertion of the timer into the map value ensured that the same value in the keys were <em>never unreferenced</em>, thus loosing the entire benefit of the Weak keys in the first place (see the &#8220;Implementation note&#8221; in the <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/WeakHashMap.html" title="WeakHashMap (Java 2 Platform SE 5.0)">WeakHashMap javadoc</a>).  The fix was simple:</p>
<pre class="code">timers.put(theTimer, null);
</pre>
<p><strong>WSEE Runtime MBeans:</strong>  WSEE (the web services stack) was creating MBeans to hold the configuration of handlers.  They were not cleared when the application was undeployed, which in itself represents a minor leak.  Unfortunately, the MBeans also (indirectly) held a reference to the Application&#8217;s ClassLoader - turning a small problem into a rather large one.</p>
<p><strong>GroupSpace use of Beehive:</strong>  GroupSpace was calling Beehive&#8217;s <code>beginContext</code> without a matching <code>endContext</code>.  Behind the scenes, Beehive created some ThreadLocals, but it does the right thing and removes them when (if) you call <code>endContext</code>.  This was fixed by balancing the context usage within a request.</p>
<p><strong>Portal Framework service manager:</strong> - Internal class in the System ClassLoader has a Map that was holding references of services to be used.  One of the services was loaded by the Application&#8217;s ClassLoader.  This was fixed by unregistering services when the application was undeployed.  Lesson:  Keep track of what you are using and let it go when it is no longer needed.</p>
<p><strong><em>Lesson:</em></strong> The Garbage Collector is not your Mom - you have to clean up after yourself around here.</p>
<p><strong>Hold Me Tight!</strong></p>
<p>Where the above references were necessary but simply not cleaned up, this grouping is more caches that are holding unnecessary or extra information.</p>
<p><strong>Log Buffer:</strong> WLS Logging keeps a buffer that holds the last 50 or so log messages for efficient display by console.  But the implementation was holding the application-scoped logger objects (rather than simply holding the text it needed to display).  The fix was to copy information from the application-scoped objects to generic system-scoped objects for the buffer.</p>
<p><strong>Resource initialization optimization:</strong>  The ResourceBase class that is the base class for our Entitlement resources, was keeping a collection of previously created objects.  It then used data from these objects to initialize fields in new instances referring to the same resource. But our Entitlement resource objects were application-scoped, and thus this collection caused leaks.  We fixed this by overriding the base object with our own intermediate implementation.  We kept the caches, but wrapped the objects in Weak and Soft references.  This is not an ideal solution, so we have planned to revisit the whole design in a future release.</p>
<p><strong>BeanELResolver cache:</strong>  The <code>javax.el.BeanELResolver</code> (used when EL is used in a JSP) caches bean properties in a static Map.  Since these bean objects are generally webapp-scoped, there is a leak.  We fixed it the same way <a href="https://glassfish.dev.java.net/issues/show_bug.cgi?id=587" title="https://glassfish.dev.java.net/issues/show_bug.cgi?id=587">Glassfish fixed it</a> by clearing the map on undeploy.  Since BeanELResolver does not have a public method to clear the map or uncache entries, this had to be done by reflection of the private map field (ugh).  The interesting bit is that BeanELResolver does have methods to provide the close/clear function, but they are private (and never referenced).</p>
<p><strong>Commons Logging in System Classpath:</strong>  Commons Logging holds a map of loggers, which it may load via the application or webapp ClassLoader.  Thus simply having the commons logging jar in your System ClassPath will trigger a leak (if logging is used from an application - as it is with Beehive).  For us, the jar was added to the system classloader inadvertently (via jar manifest entries), so the fix was to simply remove it.  However, we really can&#8217;t do anything about it if a customer decides to stick commons logging in <em>their</em> classpath.</p>
<p><strong>Glassfish JAXB:</strong>  The Glassfish implementation of JAXB caches some reflection lookups.  It has a <code>WeakHashMap</code> with <code>Class</code> objects as keys.  Good try, however the values in that map are <code>Constructor</code> objects, which themselves hold an instance to the <code>Class</code> (which therefore means the keys are strongly held, and the Map&#8217;s weak keys can never be released). We fixed this in our local version by wrapping the <code>Constructor</code> in a <code>WeakReference</code>.  We <a href="https://jaxb.dev.java.net/issues/show_bug.cgi?id=400">filed the ssue with Sun</a>, and they adopted our fix in version 2.1.6.</p>
<p><strong>LeaseManager holding a TimerManager:</strong> The LeaseManager (a new internal class) was holding a static reference to an app-scoped <code>commonj.timers.TimerManager</code>.  This one was fun because it required tripping a race condition in order to trigger the leak.  Also, in addition to being a leak, this was an error because the static reference tied the LeaseManager to a single deployed instance of a single application, so it would not work properly with multiple applications.  We fixed this by looking up the TimerManager as needed (from JNDI, like you&#8217;re supposed to do).  Yet another example of premature optimization (i.e. presuming that the JNDI lookup was too slow).</p>
<p><strong><em>Lesson</em></strong><em>:</em>  You gotta know when to hold &#8216;em; Know when to fold &#8216;em.</p>
<p><strong>The Ties that Bind</strong></p>
<p>I&#8217;ve covered the Thread and ThreadLocal issues previously, but here are the details to complete the list.</p>
<p><strong>ThreadLocals in Portal Framework:</strong> Some of the Framework JDBC code was using ThreadLocal but not cleaning up at end of request.  This was fixed by simply removing the ThreadLocal (in a finally block) at the end of the request</p>
<p><strong>new Threads in JSP compiler:</strong> See the <a href="http://dave.srednal.com/archives/13" title="Leak Patterns: new Thread">previous post</a>.  It turned out that the thread was unnecessary: a leftover from when the code was ported to the server from a different environment.  So it was just removed.</p>
<p><strong>ThreadLocals in Content Management:</strong>  Content was using ThreadLocal and not removing them after a request.  The ThreadLocals were added as a (possibly unnecessary?) performance optimization, and the fix was simply to remove them.</p>
<p><strong><em>Lesson:</em></strong>  Don&#8217;t let your code get all tied up in knots - unravel those threads.</p>
<p><strong>Final Thoughts</strong></p>
<p>If you&#8217;ve taken the time to look at these issues, you can see that the problems spanned across multiple subsystems: WLP, WLS, WLW, Apache, and Sun.  It was quite a project, and quite a fun challenge to track all these down.</p>
<p>Next, I&#8217;ll outline how we intend to keep this from happening again, and show you some tricks for your own memory leak testing.</p>
<p><!-- technorati tags start -->
<p style="text-align:right;font-size:10px;">Technorati Tags: <a href="http://www.technorati.com/tag/leak" rel="tag">leak</a>, <a href="http://www.technorati.com/tag/memory" rel="tag">memory</a>, <a href="http://www.technorati.com/tag/portal" rel="tag">portal</a>, <a href="http://www.technorati.com/tag/WebLogic" rel="tag">WebLogic</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://dave.srednal.com/archives/15/feed</wfw:commentRss>
		</item>
		<item>
		<title>LeakPatterns:  ThreadLocal</title>
		<link>http://dave.srednal.com/archives/14</link>
		<comments>http://dave.srednal.com/archives/14#comments</comments>
		<pubDate>Mon, 03 Dec 2007 22:40:43 +0000</pubDate>
		<dc:creator>dave</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://dave.srednal.com/archives/14</guid>
		<description><![CDATA[Another common source of leaks we found was related to the use of ThreadLocal.  A ThreadLocal is a way to attach some data to a Thread, so you can get at it later.  They are really useful for a couple of cases.
First, you can cache some value (presumably expensive to compute) and reuse [...]]]></description>
			<content:encoded><![CDATA[<p>Another common source of leaks we found was related to the use of <code>ThreadLocal</code>.  A <code>ThreadLocal</code> is a way to attach some data to a Thread, so you can get at it later.  They are really useful for a couple of cases.</p>
<p>First, you can cache some value (presumably expensive to compute) and reuse it later.  Since the value is associated with the Thread, it is thread-safe (baring any issues with the attached objects themselves).  This makes the <code>ThreadLocal</code> an important tool in performance optimizations.</p>
<p>Another good use of <code>ThreadLocal</code> is to hold some context-related information.  For example, maybe you need some data that is on the HTTP Request (like URLs, attributes, query parameters) in order to make an authorization decision for access to certain data.  Normally, this would mean that all that data (or the Request itself) would need to appear on the authorizer API - and on any API that called that one - and on any API calling those APIs, etc.  Or, you could toss the Request data into a <code>ThreadLocal</code> and retrieve it in the authorizer.  It becomes <em>context</em> for the call to the authorizer.  This is another really useful technique for loosely tying subsystems together.</p>
<p>But in a server environment (like WebLogic), the Threads are usually pooled and reused for request after request.  The <code>ThreadLocal</code> is associated with a Thread, and the Thread is associated with a Request - so that is good.  Except that the Thread is only <em>temporarily</em> associated with the Request.</p>
<p>So, if <code>ThreadLocal</code> objects are not managed correctly (such that their life-cycle matches that of the Request), you can get all sorts of evil things happening.  First, if you were using ThreadLocal for performance, it just might not work since one user session might be handled by many different Threads.  Worse, you might leak data from one user to another (when a user&#8217;s Request reuses a Thread containing another user&#8217;s data).</p>
<p>And in the cases I saw, if that ThreadLocal holds objects that otherwise should be garbage collected, you will get a leak.</p>
<p>The solution is to ensure that your ThreadLocal usages are properly managed.  The ThreadLocal should have the same life cycle as the Request, and you should use <code>ThreadLocal.remove() </code>&#8211; preferably in a proper finally block - to clean up at the end of your Request.<br />
<!-- technorati tags start -->
<p style="text-align:right;font-size:10px;">Technorati Tags: <a href="http://www.technorati.com/tag/leak" rel="tag">leak</a>, <a href="http://www.technorati.com/tag/memory" rel="tag">memory</a>, <a href="http://www.technorati.com/tag/portal" rel="tag">portal</a>, <a href="http://www.technorati.com/tag/ThreadLocal" rel="tag">ThreadLocal</a>, <a href="http://www.technorati.com/tag/WebLogic" rel="tag">WebLogic</a></p>
<p><!-- technorati tags end --></p>
]]></content:encoded>
			<wfw:commentRss>http://dave.srednal.com/archives/14/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
