I personally use newsrdr on both a 2010 MacBook Pro (running Safari) and on Chrome in Windows 7 to follow various tech blogs. Inevitably, Safari would always slow down on the Mac until I either restarted it or it reloaded all of my tabs. One time I had to do this and decided to check Activity Monitor first. I saw something like this:
Profiles sounds promising. Clicking on that brings up a tab with several options, including "Record Heap Allocations" and "Take Heap Snapshot". I took an initial heap snapshot, played around with the site a bit (basically: add a couple of feeds and go to Home), and took another snapshot.
Chrome has an option to compare the current snapshot with any previous snapshot, and here's what I discovered:
Of course, there should be no references to any <video> tags anywhere, since the site removes all post HTML from the DOM upon changing pages. Further investigation revealed that the feeds I had added contained embedded YouTube videos. Now I know why there are <video> tags, but why aren't they getting cleaned up?
When someone embeds a YouTube video onto a Web page, the page contains an <iframe> tag that loads the video from YouTube's Web site. An <iframe> is a HTML tag that allows a developer to load another Web page inside the existing one. This allows the developer to do cool things. Like, say, loading embedded content based on the user's browser. When an <iframe> gets parsed by the browser, a new entry gets added to the window.frames array. This reference sticks around even after the <iframe> gets removed from the DOM due to it being part of the window and not the document. There's our reference to the video right there.
Fortunately, fixing this is simple. While we can't necessarily remove the <iframe> from there, we can remove the code and DOM that YouTube created by navigating to about:blank (which produces a blank HTML page). In CoffeeScript:
_leakCleanup: () -> # We need to navigate all iframes inside the article to about:blank first. # Failure to do so results in memory leaks. frameList = this.$('iframe') for i in frameList i.contentWindow.location.href = "about:blank" frameList.remove()
After adding this code and running the same test again, I found that the amount of heap used between the two snapshots was pretty much constant. Success! I immediately checked this change into the tree.
In conclusion, memory leaks are fairly easy to find with the right tools. There's no excuse not to do at least a cursory check before releasing a new project or a change to an existing one. Hopefully this helped some people with their own Web projects.
Feel free to leave feedback below, or use the Contact link above if you run into other issues using newsrdr.