<?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>Karl Kraft &#187; Debugging</title>
	<atom:link href="http://www.karlkraft.com/index.php/category/debugging/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.karlkraft.com</link>
	<description>Just a 2 bit programmer in a 64 bit world</description>
	<lastBuildDate>Thu, 24 Jun 2010 14:20:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Don&#8217;t use non mutable objects to understand leak detection</title>
		<link>http://www.karlkraft.com/index.php/2009/04/22/dont-use-non-mutable-objects-to-understand-leak-detection/</link>
		<comments>http://www.karlkraft.com/index.php/2009/04/22/dont-use-non-mutable-objects-to-understand-leak-detection/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 04:11:27 +0000</pubDate>
		<dc:creator>Karl Kraft</dc:creator>
				<category><![CDATA[Debugging]]></category>

		<guid isPermaLink="false">http://www.karlkraft.com/?p=116</guid>
		<description><![CDATA[This is a replay of a post I recently submitted to iPhoneSDK to explain why using non-mutable objects like NSString to learn leak detection is a bad idea. The original post by Robert Scott complained that this code wasn&#8217;t showing Leaks in instruments even though it should be leaking a NSString with every pass. Robert [...]]]></description>
			<content:encoded><![CDATA[<p>This is a replay of a post I recently submitted to iPhoneSDK to explain why using non-mutable objects like NSString to learn leak detection is a bad idea.</p>
<p>The original post by Robert Scott complained that this code wasn&#8217;t showing Leaks in instruments even though it should be leaking a NSString with every pass.</p>
<p><span id="more-116"></span><br />
Robert wrote:<br />
<em>So I guess there must be<br />
something fundamental I don&#8217;t understand about leaks because I don&#8217;t<br />
see why your examples cause leaks and this code does not:<br />
</em><br />
<code>
<pre>
  static int k;
  NSString *leakyString = [[NSString alloc]  initWithFormat:@"%1d", ++k] ;
  myLabel.text = leakyString;
</pre>
<p></code></p>
<p>The answer:</p>
<p>Because they aren&#8217;t leaks.  If you try to use NSString to learn about<br />
Objective-C memory management you will get burned over and over again,<br />
because it uses tons of behind the scene tricks. NSString is not a<br />
good place to learn to leak detection.</p>
<p>You are not the only one with references to those objects.  This is<br />
going to be long and involved, so get a cup of your favorite beverage,<br />
download the <a href="http://www.karlkraft.com/wp-content/uploads/2009/04/leaksampler.zip">example code</a> and cuddle up with Xcode:</p>
<p>First off make sure you are using Xcode 3.1.2 for this demo, with the simulator set for 2.2.1.  Effects may vary by platform and by version.</p>
<p><code>
<pre>
- (IBAction)pushMe:(id)sender;
{
  static int k;
  NSString *leakyString = [[NSString alloc]  initWithFormat:@"%1d", ++k] ;
//	myLabel.text = leakyString;
  NSLog(@"%@ %p %p",leakyString,leakyString,myLabel.text);
}
</pre>
<p></code></p>
<p>This code adds the printing of the pointers to leakyString and<br />
myLabel.text  For now the assignment to myLabel.text is commented<br />
out.  Run the code and watch the output of the debugger console.  You<br />
should get something like this:</p>
<p><code>
<pre>
2009-04-22 22:17:11.443 LeakSampler[27569:20b] 1 0xa03ca9f0 0x508540
2009-04-22 22:17:11.583 LeakSampler[27569:20b] 2 0xa03c3640 0x508540
2009-04-22 22:17:11.732 LeakSampler[27569:20b] 3 0xa03c9820 0x508540
2009-04-22 22:17:11.873 LeakSampler[27569:20b] 4 0xa03c8e20 0x508540
2009-04-22 22:17:12.013 LeakSampler[27569:20b] 5 0xa03c9dc0 0x508540
2009-04-22 22:17:12.153 LeakSampler[27569:20b] 6 0xa03ca520 0x508540
2009-04-22 22:17:12.294 LeakSampler[27569:20b] 7 0xa03c92a0 0x508540
</pre>
<p></code></p>
<p>Keep pushing until you get to:</p>
<p><code>
<pre>
2009-04-22 22:17:29.193 LeakSampler[27569:20b] 48 0xa03c9cd0 0x508540
2009-04-22 22:17:29.357 LeakSampler[27569:20b] 49 0x53e040 0x508540
2009-04-22 22:17:29.505 LeakSampler[27569:20b] 50 0xa03c7100 0x508540
2009-04-22 22:17:29.662 LeakSampler[27569:20b] 51 0xa03c6120 0x508540
2009-04-22 22:17:29.810 LeakSampler[27569:20b] 52 0xa03c4c30 0x508540
2009-04-22 22:17:29.958 LeakSampler[27569:20b] 53 0x5145d0 0x508540
2009-04-22 22:17:30.107 LeakSampler[27569:20b] 54 0xa03c99a0 0x508540
</pre>
<p></code></p>
<p>Note that for run 49 and 53 the results were different.  They are in a<br />
much lower section of memory.</p>
<p>Now use &#8220;Start with Performance Tool -> Leaks&#8221; and run the app.<br />
Repeat all the way up to 54, (You will have to use Console.app to<br />
watch the progress)</p>
<p>You should notice a few things.  The pointers for 1..54, except for<br />
for 49 and 53 were the EXACT same on this run.  The only items that<br />
show up as leaks are the entries for 49 and 53, which have the lower<br />
memory addresses.</p>
<p><code>
<pre>
4/22/09 10:19:35 PM LeakSampler[27582] 1 0xa03ca9f0 0x508570
4/22/09 10:19:36 PM LeakSampler[27582] 2 0xa03c3640 0x508570
4/22/09 10:19:36 PM LeakSampler[27582] 3 0xa03c9820 0x508570
4/22/09 10:19:36 PM LeakSampler[27582] 4 0xa03c8e20 0x508570
4/22/09 10:19:36 PM LeakSampler[27582] 5 0xa03c9dc0 0x508570
</pre>
<p></code></p>
<p>You might be tempted at this point to think Leaks doesn&#8217;t detect leaks<br />
with high memory addresses.  You would be wrong. Play some more.</p>
<p>Remove the comment for setting the label, and start again without<br />
Instruments.</p>
<p><code>
<pre>
- (IBAction)pushMe:(id)sender;
{
  static int k;
  NSString *leakyString = [[NSString alloc]  initWithFormat:@"%1d", ++k] ;
  myLabel.text = leakyString;
  NSLog(@"%@ %p %p",leakyString,leakyString,myLabel.text);
}
</pre>
<p></code></p>
<p>Note the first 5 lines of output.</p>
<p><code>
<pre>
2009-04-22 22:24:53.204 LeakSampler[27717:20b] 1 0xa03ca9f0 0xa03ca9f0
2009-04-22 22:24:53.939 LeakSampler[27717:20b] 2 0xa03c3640 0xa03c3640
2009-04-22 22:24:54.431 LeakSampler[27717:20b] 3 0xa03c9820 0xa03c9820
2009-04-22 22:24:54.790 LeakSampler[27717:20b] 4 0xa03c8e20 0xa03c8e20
2009-04-22 22:24:55.087 LeakSampler[27717:20b] 5 0xa03c9dc0 0xa03c9dc0
</pre>
<p></code></p>
<p>myLabel.text should be getting a copy of the string:</p>
<p><code>
<pre>
@property(nonatomic,copy)   NSString *text; //  default is nil
</pre>
<p></code></p>
<p>Yet the pointer for both leakyString and myLabel.text are exactly the<br />
same.  This is because NSString is non-mutable and copy of a non-<br />
mutable object can simply be replaced with a reference to the exact<br />
same object to reduce memory consumption.</p>
<p>Now a few more tests.  Instead of NSStrings, create NSMutableStrings</p>
<p><code>
<pre>
2009-04-22 22:27:06.118 LeakSampler[27739:20b] 1 0x50c450 0xa03ca9f0
2009-04-22 22:27:06.431 LeakSampler[27739:20b] 2 0x53e7b0 0xa03c3640
2009-04-22 22:27:06.508 LeakSampler[27739:20b] 3 0x518200 0xa03c9820
2009-04-22 22:27:06.898 LeakSampler[27739:20b] 4 0x526210 0xa03c8e20
2009-04-22 22:27:07.267 LeakSampler[27739:20b] 5 0x53ef00 0xa03c9dc0
</pre>
<p></code></p>
<p>Note that the mutable strings are in low memory, yet the copies have<br />
the same addresses as the very first run.  The addresses for the<br />
mutable strings will be different on each run as various other parts<br />
of the system allocate and release memory.</p>
<p>Now for the fun part.  Set a break point on the line that reads:</p>
<p><code>
<pre>
  static int k;
</pre>
<p></code></p>
<p>And fire up the program in GDB.  Press the button one time and at the breakpoint, before your call to initWithFormat:,  print the objects at the first five memory addresses that keep showing<br />
up:</p>
<p><code>
<pre>
(gdb) <strong>po 0xa03ca9f0</strong>
1
(gdb) <strong>po 0xa03c3640</strong>
2
(gdb) <strong>po 0xa03c9820</strong>
3
(gdb) <strong>po 0xa03c8e20</strong>
4
(gdb) <strong>po 0xa03c9dc0</strong>
5
</pre>
<p></code></p>
<p>The NSString objects that you thought were all yours, that you loving<br />
created with a clever call to initWithFormat:, turned out to just be<br />
filthy dirty replicants of NSStrings generated before your code even<br />
ran.</p>
<p>For fun, you can find some more strings that are already created:</p>
<p><code>
<pre>
(gdb) <strong>x/20x 0xa03c3640</strong>
0xa03c3640:	0xa03b84a0	0x000007c8	0x93c78a10	0x00000001
0xa03c3650:	0xa03b84a0	0x000007c8	0x93c80194	0x00000014
0xa03c3660:	0xa03b84a0	0x000007c8	0x93c801ac	0x00000002
0xa03c3670:	0xa03b84a0	0x000007c8	0x93c801b0	0x00000011
0xa03c3680:	0xa03b84a0	0x000007c8	0x93c801c4	0x00000001
</pre>
<p></code></p>
<p>Looks like tightly packed objects in a lookup table:</p>
<p><code>
<pre>
(gdb) <strong>po 0xa03b84a0</strong>
NSCFString
</pre>
<p></code></p>
<p>Yup, a bunch of NSCFString objects.  A quick examination shows this<br />
portion of the table to be:</p>
<p><code>
<pre>
(gdb) <strong>po 0xa03c3650</strong>
HelveticaNeue-Italic
(gdb) <strong>po 0xa03c3660</strong>
88
(gdb) <strong>po 0xa03c3670</strong>
orange_middle.png
(gdb) <strong>po 0xa03c3680</strong>
B
</pre>
<p></code></p>
<p>If you add this line of code what do you think you get?</p>
<p><code>
<pre>
NSLog(@"%p",[[NSString alloc] initWithFormat:@"%@",@"orange_middle.png"]);
2009-04-22 22:38:05.504 LeakSampler[27848:20b] 0xa03c3670
</pre>
<p></code></p>
<p>In Summary, I Repeat:  If you try to use NSString or other non-mutable objects to learn about<br />
Objective-C memory management you will get burned over and over again,<br />
because it uses tons of behind the scene tricks. NSString is not a<br />
good place to learn to leak detection.</p>
<p>As for why 49 and 53 aren&#8217;t in the table?  Well I think that is blindingly obvious once you think about it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkraft.com/index.php/2009/04/22/dont-use-non-mutable-objects-to-understand-leak-detection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
