Fixing Memory Leaks With AQtime Pro


Uploaded by SmartBearSoftware on 17.10.2011

Transcript:

SPEAKER: This video will explain how to find and fix
memory leaks in applications with AQtime.
AQtime includes three profilers that trace memory
and resource leaks.
The Allocation Profiler is used to find memory leaks in
applications.
It traces the memory use in an application during the
applications run, and it allows you to determine
whether the allocated memory blocks or objects remain in
memory after the application execution is over.
Another profiler, the Reference Count Profiler,
tracks the creation and deletion of references to
interfaced objects, and allows you to pinpoint unreleased
references.
Finally, the Resource Profiler is used to find resource leaks
and resource errors in applications.
Today, we'll use the Allocation Profiler to find
memory leaks in our application.
This profiler is going to trace the memory in both
managed and unmanaged applications.
And in our example today, we'll use the Unmanaged
Allocation Application that shipped with AQtime.
OK, let's get started.
As you can see, I've already created an AQtime project for
our application, and I'm going to select
the allocation profiler.
Tracing of memory blocks requires minimal preparations
here in the set up panel in AQtime.
You may want to create class areas to specify the leaks of
which class instances you would like the profiler to
trace, but in our example here, we'll leave the default
of full check by classes selected.
That is, we're going to analyze all the classes of our
sample application.
The other thing I need to do is tell AQtime about the
application I want a profile.
And to do that, I just need to click right here, browse out
to where my application lives, and click the Open button.
And now I'm ready to start profiling.
So I'm going to press the Run button.
And when I do that, the run settings dialog appears.
I'm going to take the default settings here and click Run.
OK, AQtime has invoked my application.
Now I'm going to enter the number 10 inside this field
right here and click Execute.
When I've done that, I'm going to click Close.
And now you're going to see AQtime generate
some profiling results.
As you can see, the allocation profiler results are organized
into the classes data and objects categories.
The contents of this report panel, the details panel, the
call graph panel, and all the other panels that you see here
are all dependent upon the currently selected category.
Information about classes, their instances, and memory
blocks that are allocated after the application
terminates are store here in the report panel.
So let's double click on the classes data
collection right here.
And I want to pay attention to these values right here in the
live count column.
This column displays the number of instances and memory
blocks that currently exist in memory.
So you see right here, this class has a live count value
that is not zero.
That means that some of the objects that were created were
not destroyed when the application was closed.
So now I'm going to find out where these instances were
created and determine why they were not released.
So for each leak detected, the allocation profiler collects
information on the call stack.
That is, the hierarchy of functions that led to the
creation of the object that was not released.
The way you view the call stack data varies a little
depending on which category you're browsing, classes data
or objects.
So let's look at how you review the call stack when the
classes data category is active.
So I've got the classes data category selected there.
I've selected my C++ native memory class and I am going to
click on the call tree panel right here.
Now this panel displays the call routes
in a tree like structure.
You can see it down here.
Building the call tree can take some time, especially for
large applications.
So the call stack data is only going to be available if this
button right here, View Allocation Paths in Call Tree
is selected.
So let's expand the tree now.
So to do this I right click within the panel and I say,
Expand All.
Now what we're going to do is scroll through the list and
we're going to look for those routines whose live count
values, as you see right here, is not equal to zero.
These are the routines in which memory
allocations have occurred.
If the live count is zero, but the live count with children
column that you see right here is not zero, then that means
the allocations occurred in one of the child routines.
So in this case, to find the problematic routine, you have
to expand the tree and analyze the child routines.
So if we look through the call hierarchy here, we can scroll
down and find that the routine whose live count value is not
zero is this guy right here, the _nh_[INAUDIBLE]_debug.
The live count of this one indicates that the routine
allocated 10 memory blocks.
And so all the unreleased blocks that we've encountered
so far were allocated by this routine.
Once you find the routine, you can look at its source code in
the editor panel and find the place in which the allocated
memory can be released.
Now let me demonstrate how you can view a call stack when the
objects category selected.
You can do this in a similar way as the classes data
category, the only difference is that the call stack is
displayed in a different panel, in the details panel.
So we'll activate the objects category here, and when it's
active, the report panel displays information on the
class instances that were created during the run.
So I select the desired instance in the report panel--
let's use this first guy right here--
and then switch to the details panel.
And down here in this creation call stack, I can see a list
of functions that led up to that object creation.
As you can see, this is the same function hierarchy that
you have seen in the call tree panel when the classes data
category was selected.
Now the topmost routine is the one that created the object or
allocated the memory block.
And this is a standard C library function that
allocates memory.
And this function was called by this function right here,
which was called by this function, which was called
this function, and so on.
So in this way, we can go through the call stack until
we meet a routine that's located in our source file.
And in our case, this is the Allocation Test routine, which
is allocated here inside the AllocationDialog.cpp file.
Now to see the source code of this routine, I can just
double click it here.
And that will bring up the editor panel and position the
cursor inside the routine source code, as you can see
right here.
Now here we can see the code of the Allocation Test method.
Let me go ahead and make this a little bit bigger.
And from what I can see inside this routine, we have an array
that's being deleted right here, but there's no code
that's actually deleting the elements within that array.
So what we're going to do is add some code inside our
application that will delete all the
elements from that array.
OK I've just brought up Visual Studio, and I'm inside the
relevant source code file.
So now what I'm going to do is just add in some code that's
going to delete that array's elements.
And I'm going to put that right in here, and that
command is delete *array, and that's going to tell it to
automatically delete all the elements within that array.
OK, and then I'm going to save my project, and rebuild it.
OK so now I've switched back to AQtime, and AQtime will
automatically update the debug information for the
application model that I just rebuilt.
Now I'm going to profile my application again to see if
those memory leaks were fixed.
So we'll just click on the Run button right here.
I'm going to use the exact same settings,
again take the defaults.
AQtime is going to bring up my application.
Here we go.
We'll put in 10 again and click Execute.
Then we'll click Close.
AQtime will generate its results.
And you can see right here, in the live count column, they're
all coming up as zero.
And if we look on the objects section here, you can see that
there are no objects listed.
So that means that we've corrected the memory leak.
Now the last thing I'd like to mention is that, like other
AQtime profilers, the Allocation Profiler can
generate results not only when the application exits, but
also during the profiler run.
You can tell AQtime to generate results by selecting
Run, Generate Results, or by pressing the Get Results
button on the toolbar, which is right here.
And then AQtime will show you all the objects living in
memory at that point in time, and you can see whether there
are unnecessary objects going on in your application.
This concludes our video on fixing
memory leaks with AQtime.
I hope it will help you improve your code and provide
rock solid applications.
If you have any questions, please don't hesitate to
contact our sales managers or our support team at
smartbear.com/support.
We wish you luck and hope you enjoy working with AQtime.