Memory leak checking using Instruments on Mac

2019-02-18 15:05发布

问题:

I've just been pulling my hair out trying to make Instruments cough up my deliberately constructed memory leaks. My test example looks like this:

class Leaker
{
public:
    char *_array;
    Leaker()
    {
        _array=new char[1000];
    }

    ~Leaker()
    {
    }
};

void *leaker()
{
    void *p=malloc(1000);
    int *pa=new int[2000];
    {
        Leaker l;
        Leaker *pl=new Leaker();
    }
    return p;
}

int main (int argc, char **argv)
{
    for (int i=0; i<1000; ++i) {
        leaker();
    }
    sleep(2); // Needed to give Instruments a chance to poll memory
    return 0;
}

Basically Instruments never found the obvious leaks. I was going nuts as to why, but then discovered "sec Between Auto Detections" in the "Leaks Configuration" panel under the Leaks panel. I dialed it back as low as it would go, which was 1 second, and placed the sleep(2) in in my code, and voila; leaks found!

As far as I'm concerned, a leak is a leak, regardless of whether it happens 30 minutes into an app or 30 milliseconds. In my case, I stripped the test case back to the above code, but my real application is a command-line application with no UI or anything and it runs very quickly; certainly less than the default 10 second sample interval.

Ok, so I can live with a couple of seconds upon exit of my app in instrumentation mode, but what I REALLY want, is to simply have Instruments snapshot memory on exit, then do whatever it needs over time while the app is running.

So... the question is: Is there a way to make Instruments snapshot memory on exit of an application, regardless of the sampling interval?

Cheers,

Shane

回答1:

Instruments, in Leaks mode can be really powerful for leak tracing, but I've found that it's more biased towards event-based GUI apps than command line programs (particularly those which exit after a short time). There used to be a CHUD API where you could programmatically control aspects of the instrumentation, but last time I tried it the frameworks were no longer provided as part of the SDK. Perhaps some of this is now replaced with Dtrace.

Also, ensure you're up to date with Xcode as there were some recent improvements in this area which might make it easier to do what you need. You could also keep the short delay before exit but make it conditional on the presence of an environment variable, and then set that environment variable in the Instruments launch properties for your app, so that running outside Instruments doesn't have the delay.



回答2:

Most unit testing code executes the desired code paths and exits. Although this is perfectly normal for unit testing, it creates a problem for the leaks tool, which needs time to analyze the process memory space. To fix this problem, you should make sure your unit-testing code does not exit immediately upon completing its tests. You can do this by putting the process to sleep indefinitely instead of exiting normally.

https://developer.apple.com/library/ios/documentation/Performance/Conceptual/ManagingMemory/Articles/FindingLeaks.html



回答3:

I've just decided to leave the 2 second delay during my debug+leaking build.