Hey Rolf,
Thanks for the reply! I've gotten more familiar with Instruments now, and I've started taking several heapshots as you advised. When looking at the 1000+ objects that are making up the 100kb+ memory leak, it essentially just looks like everything my app is allocating. So I believe the real question I need to answer is "Why isn't Mono collecting these?" This is where I turn to the mono profiler and get really confused. It hardly shows anything, and most of what it does show isn't my code (it's all System.* and MonoTouch.* types). This is the view with Inversed References: http://i.imgur.com/Z0MuD.png If my goal is to figure out why the Mono GC isn't collecting something, I assume Instruments won't tell me that, correct? Will the mono profiler tell me that? Is there any other way to find out? Thanks! From: Rolf Bjarne Kvinge [mailto:[email protected]] Sent: Tuesday, October 30, 2012 10:55 AM To: Randy Ficker Cc: [email protected] Subject: Re: [MonoTouch] Understanding the memory profiler Hi, On Mon, Oct 29, 2012 at 9:07 AM, Randy Ficker <[email protected]> wrote: I believe my MonoTouch app is leaking memory, and I've been struggling at figuring out why. By using Instruments I can see the allocated memory grow and grow over the life of the app, eventually causing the app to die after 10 minutes or so of general use on my 3GS. To help isolate the problem, I first picked a specific action in my app I can easily repeat - just opening a menu and closing it again, which shouldn't leave any garbage behind as the code is well-contained. Using Instruments, I can see that just opening and closing this menu adds about 90KB of allocations each time. If I open and close it 11 times, I've added a megabyte to my app's memory use. I first tried enabling SGen and then the reference counting extension. Neither configuration changed the memory allocated. I tried commenting out parts of the menu that I thought might be leaking (images, custom-draw views, etc.). Doing this did reduce the memory leakage, but even if I comment out all of the functionality (to the point where my menu came up blank) it was still leaking 40KB each time. So I still feel I'm missing something fundamental. I was concerned that the garbage collector might just not be running, flawing my test results. I added a call to GC.Collect() but that didn't change anything. I also tried doing it 50 times in a row, leaking over 4 megs of memory, to see if the GC would eventually collect it all. It never did. Throughout this, I've been trying to understand the mono memory profiler. Following the instructions, I take a shot, open and close my app's menu, and take another shot, then diff them, and I see this: http://i.imgur.com/N4Ngb.png. Checking "Roots only" doesn't change anything (the three new columns are empty). Instruments->Leaks shows this: http://i.imgur.com/hbJQ1.png First: you should do more than 1 heapshot, do several until the heap growth settles around a ~fixed amount, otherwise there will be some noise (iOS caches some this heavily) in the output (this is true for the Mono profiler too). Then you can start examining the result - your screenshot shows various objects which haven't been freed. You can see the stack trace for where each of these objects were created by expanding it and selecting a specific instance, then showing the extended detail view (in the toolbar, there are three buttons above the label "View" - click on the right-most button). For comparison, I also ran the profiler against my code with virtually all of my code commented out (it was just bringing up a blank menu). Memory leak is about 40KB in this scenario: http://i.imgur.com/eIlK7.png I'm very confused by these results. My questions are: 1. What is <Other Root> and why does it have thousands of instances that total 0 memory? This appears to be the common factor in both of them. Other Roots are usually GCHandles - you can normally just ignore these roots, they are very rarely the cause for any problems. 2. In the first one, it says 20KB of strings leaked. How can I tell where these are coming from or why they aren't being collected? 3. What uses System.WeakReference and why would it be leaking? For both 2. and 3. you should check the "Inverse References" checkbox, and then expand the treeview for the objects you want to examine - this will allow you to see what types reference the topmost type. 4. The mono profiler only seems to account for a small part of the total memory being leaked. Is there anything else I can try? The mono profiler only knows about managed memory, not everything allocated in the app (only Instruments have a global knowledge of memory in the app, but it can be tricky to get the interesting information out of Instruments). 5. What else can I do to try and figure out why my app is continually growing in memory? I feel like I'm missing something fundamental here. I'd appreciate any advice anyone can offer! _______________________________________________ MonoTouch mailing list [email protected] http://lists.ximian.com/mailman/listinfo/monotouch
_______________________________________________ MonoTouch mailing list [email protected] http://lists.ximian.com/mailman/listinfo/monotouch
