Techniques for profiling memory in Safari desktop and iOS?
Asked Answered
S

2

32

Updated 10/21: Changed title and question in order to possibly get an answer (other than "no").

We're experiencing leaks in Safari (confirmed in Windows and Mac, suspected in iOS). Are there any Safari extensions that lets one profile JavaScript/DOM memory usage to discover potential leaks? Better yet, is there any tool that can be used on iOS or in the Apple iOS emulator? What are suggested techniques for discovering what may be causing memory leaks in JavaScript/DOM in Safari? And does anyone know of ANY way to access memory information for iOS?

Background

We're developing an iOS Safari web application that uses the single-page app paradigm, loading 100s of full-screen images. We've bypased the normal 6.5 MB iOS Safari image limit by resetting the source for the image tags, but now we're running into what I believe is a memory leak in iOS Safari. After loading ~250-300 images iOS Safari simply stops loading the images, due to what we suspect is a memory leak. Not surprising, given that the same leak appears both in Safari for Windows and Safari for Mac - on Windows it is especially bad; for every new full-screen high res image, another 10-15 MB of memory is consumed, if we switch to lower res images it still gobbles up ~5 MB per image.

In Windows we've isolated the leak to the simple act of rendering the image in the browser viewport - we have a carousel of images, and even with zero DOM manipulation, by simply translating (3d) the image through the viewport, memory is allocated and never released. On Windows, memory consumption can quickly escalate to ~1.5 GB, at which point Safari simply crashes. On Mac it's not as bad, but memory easily jumps from 100 MB at the start to 500MB and beyond. In comparison, a Chrome tab/process hosting the same page grows from about 33MB to ~120MB and then stabilizes.

Attempted Workarounds

We have tried deleting the individual image tags and replacing them with the placeholder image rather than resetting them, but this does not seem to alleviate the problem, and also causes performance problems, presumably due to DOM churn. Interestingly, deleting/detaching ALL the images does work - as soon as the command executes, the memory is released. However this causes its own problems, managing the UI state, and building the carousel back up also takes a noticeable amount of time. Refreshing the page is another workaround, but that causes even more UX disruption.

Update 04/10: Just an update on what we ended up doing: iOS 4.2 introduced a limitation that cuts off a 3D transformed Div at 122,900 pixels. Not sure why, but it forced us to re-architect and go with a dynamic carousel instead of our previous static filmstrip.

Second, we found that using divs with background images work better than images themselves. This seems like a yet another bug in Safari, or at best an inconsistent limitation implementation.

end update

Thoughts? If you have encountered suspected leaks in Safari, what has been your approach to work around them?

Savadove answered 19/10, 2010 at 17:57 Comment(0)
E
37

When you install the iOS SDK, a utility named Instruments is also installed. It can track all sorts of usage stats, including memory (there is even a "Leaks" template). The great thing is that it can track both the iPhone/iPad simulator and any connected iOS development device. It also, of course, can be used to monitor memory usage in Mac OS, so it may help with Safari as well. You can find Instruments in /Developer/Applications.

Something else that is handy is that whenever you sync your iPad/iPhone with iTunes, it also syncs any crash reports from the device to your computer. They can be found at ~/Library/Logs/CrashReporter/MobileDevice/[Device Name]/.

One thing we found when developing for the iPad in particular was that it was very prone to crashing due to memory issues, particularly in image heavy applications like ours. One thing we learned was that just removing a DOM element does not mean that element will be garbage collected by the browser. We found that setting the image src (or background-image, if it was a div) to an empty string before removing it from the DOM helped immensely.

Not sure if any of that helps, but hopefully getting Instruments up and running will give you a better idea of where all that memory is going.

Eucaine answered 22/10, 2010 at 3:29 Comment(5)
Brad, thanks - this is helpful (and up-voted). I'm inclined to award you the answer and the bounty, but want to give it a few days before I pull the trigger...Savadove
Brad, Answer selected, bounty awarded. Thanks for your insight.Savadove
Just a note: setting the src property of an Image to null instead of an empty string will prevent some other browsers (noted with Chrome) from making an additional request to the same URL as the web page.Plutonian
I just tested setting null but Chrome tried to download an image at the address currentpage/null. I would suggest setting it to a short image data URI instead like it's suggested on this article about Mobile Safari's image resource limit. img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7Current
This answer should explain how to get Instruments set up and monitoring Safari.Atonsah
M
1

The profiling tools built into Safari have improved a lot since this question was first asked.

Assuming you need to profile the memory of a web application in mobile Safari, you can use a USB cable to connect your mobile device to Mac and use remote debugging to pull up the Web Inspector for a mobile browser tab (setup instructions here).

Then, in the Web Inspector's timelines tab, you can click edit to choose options for profiling (more details in the docs here). The Memory and JavaScript Allocations choices are most helpful for memory-related issues.

Finally, you can click the red circle (record) to record while you take actions in the app and stop the recording when you're ready to inspect the memory usage.

Maturation answered 14/11, 2022 at 21:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.