{"id":387,"date":"2010-04-08T18:37:12","date_gmt":"2010-04-09T02:37:12","guid":{"rendered":"http:\/\/www.lostvectors.com\/blog\/?p=387"},"modified":"2010-10-11T12:12:38","modified_gmt":"2010-10-11T20:12:38","slug":"tell-me-where-it-hurts-part-2-not-all-my-fault","status":"publish","type":"post","link":"https:\/\/www.lostvectors.com\/blog\/2010\/04\/08\/tell-me-where-it-hurts-part-2-not-all-my-fault\/","title":{"rendered":"Tell Me Where It Hurts Part 2: Not (All) My Fault"},"content":{"rendered":"<style type=\"text\/css\"> \n<!--\n.style1 {color: #006600}\n.style3 {\n\tcolor: #80ff00;\n\tfont-weight: bold;\n}\n.style4 {color: #FF0000}\n.style6 {color: #FF00FF}\n.style7 {color: #00FFFF}\n.style_code {\nfont-family: \"Courier New\", Courier, monospace;\nfont-size: 12px;\n}\n-->\n<\/style>\n<p>So after doing some further tests I was able to pinpoint  code that would result in memory leaks. The code itself looked harmless and  functionally it worked.<\/p>\n<p>I narrowed a leak to a &ldquo;doSomething&rdquo; function in my Util class.  I knew it caused an error because when I turned the function into a no-op the  leak went way. So I knew that something in that code was causing the leak. But  just looking at it, it made no sense whatsoever why there was a leak. <\/p>\n<p>Example original code:<\/p>\n<p><span class=\"style_code\"><\/p>\n<p>public static function doSomething(clip:MovieClip):void<br \/>\n{<br \/>\n&nbsp;&nbsp;&nbsp;<span class=\"style4\">var  mc:MovieClip;<\/span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br \/>\n&nbsp;&nbsp;&nbsp;do some  sort of gotoFrame logic on clip<br \/>\n&nbsp;&nbsp;&nbsp;for all children in clip {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if  child is MovieClip {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"style4\">mc<\/span>  = MovieClip(child);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doSomething(<span class=\"style4\">mc<\/span>);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br \/>\n&nbsp;&nbsp;&nbsp;}<br \/>\n}<\/p>\n<p><\/span><\/p>\n<p>This code recursively does something on a movieclip and all  of its children that are also movieclips.<\/p>\n<p><span class=\"style_code\"><\/p>\n<p>public static function doSomething(clip:MovieClip):void<br \/>\n{<br \/>\n&nbsp;&nbsp;&nbsp;do some sort of gotoFrame logic on  clip<br \/>\n&nbsp;&nbsp;&nbsp;for all children in clip {<br \/>\n&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if  child is MovieClip {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doSomething(<span class=\"style4\">MovieClip(child)<\/span>); \/\/ cast child and send<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br \/>\n&nbsp;&nbsp;&nbsp;}<br \/>\n}<\/p>\n<p><\/span><\/p>\n<p>Notice that I removed the local variable &ldquo;mc&rdquo; and just  passed a MovieClip casted version of child as the parameter. There was <span class=\"style4\">NO<\/span>  functional reason for this change. I really had doubts that this would have  any affect. After all, &ldquo;var mc:MovieClip&rdquo; is a local variable and <span class=\"style4\">should be<\/span> marked for garbage collection at the end of the recursive function call. The function does in fact end  so don&rsquo;t think it&rsquo;s runaway recursion. We&rsquo;re dealing with clips that are just 3  subclips deep at most and I use this function several times a second on many  clips without any hanging.<\/p>\n<p>When I tested the second version of the code there was no  leak to be found. Undeniably the code change had some effect. <span class=\"style4\">Why?!?<\/span> My theory  was that since I was calling this static function from inside a non-static  instance of an object that maybe Flash had some obscure rule about local  variables inside static functions and it caused the program to hold on to all  references to MovieClips thus preventing them from ever being garbage  collected. <\/p>\n<p>I don&rsquo;t pretend to know everything there is about Flash or  how it works. But something about this seemed real fishy. I often like to blame  flash for its bugs but I do this mostly to complain about the IDE. I like to  trust that the flash player is solid and without error&#8230; yeah, so naive. It&rsquo;s  not a good practice to blame the flash player because then you may write off  real issues  as &ldquo;flash bugs&rdquo; when in fact they <em>are your fault<\/em>. I try hard to give flash the  benefit of the doubt. I&rsquo;ve done so for this entire week. I&rsquo;ve torn apart my  code to pinpoint the causes for memory leaks. I&rsquo;ve been rebooting my game  practically one feature at a time just to find issues. This is how I found the  issue mentioned above.<\/p>\n<p>Even though I felt a little relieved that I&rsquo;ve finally &ldquo;fixed&rdquo;  one of the leaks, something didn&rsquo;t feel right about that fix. I didn&rsquo;t feel it  was my fault. It felt like a hack solution and what bugged me the most was that  I had no real understanding of the issue. There was no white-paper or  release-notes that I was aware of that explained the issue I uncovered. I&rsquo;m not  sure I can even recreate the leak using anything but the complex environment of  my game code. I&rsquo;d love to make a lean code example of the issue without my  entire game attached and submit it to Adobe and ask &ldquo;why?&rdquo;. I felt run down. A  little defeated&#8230;<\/p>\n<p>AND THEN&#8230; On a whim, I decided to test the code on a different  machine. I should have done in the first place. It&rsquo;s good practice to test the  application in different environments with different browsers. I don&rsquo;t know why  I assumed my environment was error free. I was wrong.<\/p>\n<p>I took the same exact game that had the leaky code and ran  it in IE on a Windows XP 32 bit system. I was originally running on Windows 7  64bit using IE 32 bit. Using the same problematic version of my game but using the XP machine with latest flash installed the game had <span class=\"style1\">NO MEMORY  LEAK<\/span>. At that point I was mad. All this time I thought it was my fault. All  this time I spent turning code on and off and locating obscure areas of code  that my flash player decided it just didn&rsquo;t like willy-nilly.<\/p>\n<p>So now I go back and test variations of my game using past tests  that failed before to see if they would pass this time on the different  computer. Unluckily only some of the previous failed tests passed this time so I  still had memory leaks that were my fault somewhere. OR the flash player on  this other PC had a different kind of criteria for giving me faulty memory  management. Either way I had to fix something because chances are I&rsquo;m not the  only one with the issue. However now I&rsquo;m left second guessing whether or not  the leaks are my fault or the player&#8217;s.<\/p>\n<p>All I can do now is do further tests and isolate the areas  of code that cause the game to break. Even if it&rsquo;s a dumb flash bug and not my  fault I still have to adapt since no amount of yelling at Adobe is going to fix  this issue right this second.<\/p>\n<p>The plus side to all of this testing is that it&rsquo;s giving me  a good understanding of how much memory certain features use. This will help me  determine where I need to optimize the game to make it run smoother.<\/p>\n<p>UPDATE: The saga continues&#8230; Read <a href=\"http:\/\/www.lostvectors.com\/blog\/2010\/04\/09\/tell-me-where-it-hurts-part-3-security-checkpoints\/\">Part 3<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So after doing some further tests I was able to pinpoint  code that would result in memory leaks. The code itself looked harmless and  functionally it worked.<\/p>\n<p>I narrowed a leak to a &ldquo;doSomething&rdquo; function in my Util class.  I knew it caused an error because when I turned the function into a no-op the  leak went way. So I knew that something in that code was causing the leak. But  just looking at it, it made no sense whatsoever why there was a leak. <\/p>\n<p>Example original code:<\/p>\n<p> <a class=\"continue-reading-link\" href=\"https:\/\/www.lostvectors.com\/blog\/2010\/04\/08\/tell-me-where-it-hurts-part-2-not-all-my-fault\/\"> Continue reading <span class=\"meta-nav\">&rarr; <\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-387","post","type-post","status-publish","format-standard","hentry","category-devlog"],"_links":{"self":[{"href":"https:\/\/www.lostvectors.com\/blog\/wp-json\/wp\/v2\/posts\/387","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lostvectors.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lostvectors.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lostvectors.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lostvectors.com\/blog\/wp-json\/wp\/v2\/comments?post=387"}],"version-history":[{"count":9,"href":"https:\/\/www.lostvectors.com\/blog\/wp-json\/wp\/v2\/posts\/387\/revisions"}],"predecessor-version":[{"id":404,"href":"https:\/\/www.lostvectors.com\/blog\/wp-json\/wp\/v2\/posts\/387\/revisions\/404"}],"wp:attachment":[{"href":"https:\/\/www.lostvectors.com\/blog\/wp-json\/wp\/v2\/media?parent=387"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lostvectors.com\/blog\/wp-json\/wp\/v2\/categories?post=387"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lostvectors.com\/blog\/wp-json\/wp\/v2\/tags?post=387"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}