Memory Leaks in main.m while profiling in Instruments?

In my one of the app i am getting memory leak in UIKit,UIFoundation and QuartzCore. When i go for call tree it showing leak in main.m. I really didn't have any clue why is this happening. You can see the screen shots of the memory leak below.

In Call Tree

How to resolve this leaks?

MEMORY LEAK CODE

- (void) showCustomPrices
{

int priceValue = 0;
NSArray* priceSplitValue = [btnpriceButton.titleLabel.text componentsSeparatedByString: @"."];
NSString* priceFinal = [priceSplitValue objectAtIndex:0];

for(int i=0;i<[priceArray count];i++)
{ 
    if([[priceArray objectAtIndex:i] isEqualToString:priceFinal]){
        priceValue = i; 
    }
}


    //Assign the cocktail to picker view
    priceActionsheet = [[UIActionSheet alloc] initWithTitle:nil
                                              delegate:self
                                     cancelButtonTitle:nil
                                destructiveButtonTitle:nil
                                     otherButtonTitles:nil];//as we want to display a subview we won't be using the default buttons but rather we're need to create a toolbar to display the buttons on

    [priceActionsheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];

    CGRect pickerFrame = CGRectMake(0, 40, 0, 0);

    pricePickerview = [[UIPickerView alloc] initWithFrame:pickerFrame];
    pricePickerview.showsSelectionIndicator = YES;
    pricePickerview.dataSource = self;
    pricePickerview.delegate = self;


    [priceActionsheet addSubview:pricePickerview];
    //[pickerView release];

    priceToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 485, 44)];
    priceToolbar.barStyle = UIBarStyleBlackTranslucent;
    [priceToolbar sizeToFit];

    NSMutableArray *barItems = [[NSMutableArray alloc] init];

    UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
    [barItems addObject:flexSpace];

    UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneButtonPressed:)];
    [barItems addObject:doneBtn];

    UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelButtonPressed:)];
    [barItems addObject:cancelBtn];

    [pricePickerview selectRow:priceValue inComponent:0 animated:YES];//Memory leaks shows 100% here

    [priceToolbar setItems:barItems animated:YES];

    [priceActionsheet addSubview:priceToolbar];

    [priceActionsheet addSubview:pricePickerview];

    [priceActionsheet showInView:self.view];  

    [priceActionsheet setBounds:CGRectMake(0, 0, 485, 320)];

}

Any help is much appreciated.

Finally i solved my problem by moving the picker view allocation/initialisationpart from the method showCustomePrices to viewwillAppear. Which works awesome without any memory leaks.

What is happened before is whenever i click the button it popups the pickerview with memory allocation. Thats why the memory leak is happened.

Now after moving in to viewwillAppear it just allocating on first time when the view gets loaded. Then Picker View is accessed without any memory allocation. So memory leaks is removed.

install windbg. you need to make sure you get the correct version x86 or x64 depending on your dump. here is a direct link to the download for x86.

on that, you need to ensure you took the correct dump. you can use task manager to create the dump file (right click on process -> create dump file). if you're on 64bit and your process is x86 use the 32bit version of task manager (c:windowssyswow64taskmgr.exe) to take the dump file. see my article for more info on taking dump files, eg if you're on xp and need to use windbg to create the dump file.

warning there's a fairly steep learning curve and things might not work exactly as described here so come back with any issues.

i'm assuming you're using .net4 given you can open the dump in visual studio. here's a very quick guide to help you work with your dmp file:

1) run windbg, set symbols path (file -> symbol search path) to

srv*c:symbols*http://msdl.microsoft.com/download/symbols

2) open crash dump or drag your .dmp file onto windbg.

3)type this into the command window

.loadby sos clr

(fyi, for .net 2, the command should be .loadby sos mscorwks)

4) then type this

!dumpheap -stat

which lists the type of objects and their count. looks something like this:

you will have to analyze this in the context of your application and see if anything appears unusual.

there is much more to windbg, google is your friend.

for the simplest approach - skip to the bottom to read about the description of doing that with visual studio 2013.


now there might be some new tools - perhaps something in the updated visual studio and i would love to find about these, but i tried windbg before with some success. here are my old notes on how to do that:

1. create dump file from process manager
2. run windbg (x64)
3. file/open crash dump… (crtl+d)
4. run following:

lm
.load c:windowsmicrosoft.netframework64v4.0.30319sos.dll
.sympath srv*c:localsymbols*http://msdl.microsoft.com/download/symbols
.symfix
.reload
!dumpheap -stat

note that if your process if x86, especially if you are running on a x64 version of windows - you will need to use an x86 version of the debugger (windbg ships both versions) to save the dump. sos, which is a managed memory debugging extension for windbg does not support debugging x64 bit dumps of x86 bit processes. you will then also need to update the sos path respectively, so it looks like this:

.load c:windowsmicrosoft.netframeworkv4.0.30319sos.dll

possibly not all of these commands are necessary, but this is what worked for me.

now you can find the type of the object that seems to exist in too many instances

!dumpheap -type typename

where type name is just the name of the type - no fully qualified namespace necessary.

now you can check what keeps this object in memory:

!gcroot object_address

live debugging didn't work for me since the app seems to get suspended when you attach a debugger. i think i saw an option somewhere to make the app stay in memory, but i forgot where, but for memory profiling - looking at a static dump file might be enough.


you can download windbg as part of windows sdk or as a standalone download of "debugging tools for windows" from here.

to create a dump file - go to task manager, right click a proces and select "create dump file".


some more links:

http://blogs.microsoft.co.il/blogs/sasha/archive/2012/10/15/diagnosing-memory-leaks-in-managed-windows-store-apps.aspx

http://blogs.msdn.com/b/delay/archive/2009/03/11/where-s-your-leak-at-using-windbg-sos-and-gcroot-to-diagnose-a-net-memory-leak.aspx

http://social.msdn.microsoft.com/forums/en-us/winappswithcsharp/thread/f3a3faa3-f1b3-4348-944c-43f11c339423

http://msdn.microsoft.com/en-us/library/bb190764.aspx

http://blogs.msdn.com/b/dougste/archive/2009/02/18/failed-to-load-data-access-dll-0x80004005-or-what-is-mscordacwks-dll.aspx


*edit

according to .net memory allocation profiling with visual studio 2012 by stephen toub - perfview tool supports analyzing leaks in .net windows store apps. check an article and video walkthrough with vance morrison here.


*edit 2

visual studio 2013 preview adds a new option to analyze managed memory heaps from dump files. to do it - simply pause your app in the visual studio debugger, save your current dump through debug/save dump as, then resume execution and use your app until your suspected leak happens and do another dump. then go to file/open/file and open the second dump file. to the right of the dump summary in the "actions" panel you'll see a "debug managed memory" action. select that and then in "select baseline" select your first dump file. you will see a list of objects on the managed heap, grouped by type, with count diffs. note that you would typically first look at the objects with low, non-zero count differences to track a single leak source. you can drill into the list of objects and see what keeps them in memory by expanding the tree in the reference graph view.

found the answer. fredrik's response got me thinking. i was creating an instance of nsurlresponse and nserror which i was then passing to the sendsynchronousrequest method. according to the memory management document of the iphone, this should not be done. we just need to pass a reference to the nsurlresponse and nserror objects to the method and the method takes care of creating and releasing the objects.

hope that helps someone else. thanks a lot for the answers everyone.

you should just disable arc. when you enter backgroud, then if you don't use it it is being released. in swift create avaudioplayer as unmanaged<t> object.


Tags: Iphone Ios Memory Management Memory Leaks