"Damn system has a memory leak problem", due to various factors in the project, there is always a complaint that there is a memory leak, after the system has been running for a long time, less usable memory, even caused some service failure. A memory leak is one of the most common errors that is most difficult to discover because it does not cause any problems unless you run out of memory or call malloc to fail. In fact, you spend a lot of time dealing with how to properly free your memory when you use a language that has no garbage-collection mechanisms, such as C + +. If the program runs long enough, such as a background process running on the server, as long as the server is running without downtime, a small error can have a significant impact on the program, such as causing some critical services to fail.
For memory leaks, I have deep experience! Internship, the Company a project there is a memory leak problem, the code of the project two very large, background process is also more, causing memory leaks in the place is difficult to find. This opportunity is my on how to find the memory leak problem, have a certain experience, behind their own to do the relevant experiments, here I share how the memory leaks debug lookup, the main content is as follows:
- 1. Introduction to memory leaks
- 2. Memory leak detection under Windows platform
- 2.1. Detect if there is a memory leak problem
- 2.2, locate the specific memory leak place
- 3. Memory leak detection under Linux platform
- 4. Summary
In fact, Windows, Linux under the memory detection can be introduced in detail, methods and tools far more than the article introduced, my method is not optimal, if you have a better way, also please tell me and you.
1. Introduction and consequences of memory leaks
This defines a memory leak in Wikipedia: In Computer science, a memory leak is a situation in which a program fails to release memory that is no longer in use due to negligence or error. A memory leak does not mean that there is physical disappearance, but that after the application allocates a piece of memory, because of a design error, it loses control of the memory before releasing the memory, resulting in a waste of memory.
One of the most elusive and hardest-to-detect errors is a memory leak, which is a bug that failed to properly release previously allocated memory. A small memory leak that occurs only once may not be noticed, but a program that leaks large amounts of memory or leaks a growing number of programs may exhibit a variety of symptoms: from poor performance (and gradual degradation) to full memory exhaustion. Worse, a leaking program might use too much memory to fail another program, leaving the user unable to find the real source of the problem. In addition, even harmless memory leaks can be a symptom of other problems.
Memory leaks can reduce the performance of your computer by reducing the amount of available memory. Eventually, in the worst case, too much free memory is allocated, causing all or part of the device to stop working properly, or the application crashes. Memory leaks may not be serious and can even be detected by conventional means. In modern operating systems, an application that uses a routine within the existing program terminates when it is released. This means that a memory leak in a short-running application does not cause serious consequences.
In the case of affair, memory leaks lead to more serious consequences:
- The program runs out of control and consumes more and more memory over time (such as background tasks on servers, especially background tasks in embedded systems, which may be ignored for many years after they are run);
- New memory is allocated frequently, such as when displaying computer games or animated video images;
- The program can request memory that is not freed (such as shared memory), even when the program terminates;
- Leaks occur within the operating system;
- Leakage occurs in the critical drive of the system;
- Memory is very limited, such as in embedded systems or portable devices;
- When running on a termination, the memory is not automatically released on top of the operating system (such as AmigaOS), and once lost can only be restored by a reboot.
Here are some examples of how to detect a memory leak:
?
12345678910111213141516171819 |
#include <stdlib.h>
#include <iostream>
using
namespace
std;
void
GetMemory(
char
*p,
int
num)
{
p = (
char
*)
malloc
(
sizeof
(
char
) * num);
//使用new也能够检测出来
}
int
main(
int
argc,
char
** argv)
{
char
*str = NULL;
GetMemory(str, 100);
cout<<
"Memory leak test!"
<<endl;
//如果main中存在while循环调用GetMemory
//那么问题将变得很严重
//while(1){GetMemory(...);}
return
0;
}
|
In practice it is not so simple, if it is so simple and no other way, the programmer can see the problem at a glance, this program is only for testing.
2, memory leak detection under Windows Platform 2.1, detect the existence of a memory leak problem
The Visual Studio debugger and the C run-time (CRT) library below the Windows platform provide us with an effective way to detect and identify memory leaks in the following principles: Memory allocations are implemented through the CRT at runtime, as long as they are recorded separately when allocating memory and freeing memory. At the end of the program, you can determine if there is a memory leak by comparing the records that allocate memory and free memory. The methods for enabling memory detection in VS are as follows:
- STEP1, the following statements are included in the program: (#include statements must take the order shown above. If you change the order, the function that you use may not work correctly. )
?
123 |
#define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> |
By including Crtdbg.h, the malloc and free functions are mapped to their debug versions, _malloc_dbg and _free_dbg, which track memory allocations and releases. This mapping occurs only in the debug version (where _DEBUGis defined). The release version uses the normal malloc and free functions.
The #define statement maps the base version of the CRT heap function to the corresponding "Debug" version. The statement is not absolutely necessary, but the memory leak dump contains less useful information if the statement is not available.
- STEP2, after you add the above statement, you can dump the memory leak information by including the following statement in your program, which should normally be placed exactly before the program exits location:
?
At this point, the complete code is as follows:
View Code
When you run the program under the debugger, _CrtDumpMemoryLeaks displays the memory leak information in the Output window. The memory leak information is as follows:
If you do not use the #define _CRTDBG_MAP_ALLOC statement, the memory leak dump will resemble the following:
When _crtdbg_map_alloc is undefined, it displays:
The memory allocation number (within curly braces).
Block type (normal, client, or CRT).
"Normal block" is the normal memory allocated by the program.
A "client block" is a special type of memory block used by an MFC program for objects that require destructors. The MFC new operation creates a normal block or client block based on the needs of the object being created.
A "CRT block" is a block of memory allocated by the CRT library for its own use. The CRT library handles the release of these blocks, so you are unlikely to see them in a memory leak report unless a critical error occurs (such as a corrupted CRT library).
The following two types of blocks are not seen in the memory leak information:
"Free blocks" are blocks of memory that have been freed.
The Ignore block is a block that you have specifically tagged, so it does not come out of the memory leak report.
When _CRTDBG_MAP_ALLOC is defined, it also displays the files in which the leaked memory is allocated. The number in parentheses after the file name (10 in this example) is the line number in the file.
Note: Calling _CrtDumpMemoryLeaks will be very easy if the program always exits in the same location. If the program exits from multiple locations, you do not need to place a call to _CrtDumpMemoryLeaks at each possible exit, and you can include the following call at the beginning of the program:
View Code
The statement automatically calls _CrtDumpMemoryLeakswhen the program exits. You must set both the _CRTDBG_ALLOC_MEM_DF and the _crtdbg_leak_check_df two bit fields as shown earlier.
2.2, locate the specific memory leak place
From the above method, we can almost locate where to call the memory allocation function malloc and new, such as the GetMemory function in the example above, that is, line 10th! However, it is not possible to locate where the memory leaks caused by getmemory () are called, and there may be many calls to getmemory in large projects. How do I navigate to where to call getmemory-caused memory leaks?
Another technique for locating a memory leak involves taking a snapshot of the memory state of the application at a critical point. The CRT library provides a structure type _crtmemstate, which you can use to store snapshots of the state of memory:
?
1 |
_CrtMemState s1, s2, s3; |
To take a snapshot of the memory state at a given point, pass the _crtmemstate structure to the _CrtMemCheckpoint function. This function fills this structure with a snapshot of the current memory state:
?
1 |
_CrtMemCheckpoint( &s1 ); |
By passing the _crtmemstate structure to the _CrtMemDumpStatistics function, you can dump the contents of the structure at any point:
?
1 |
_CrtMemDumpStatistics( &s1 ); |
To determine if a memory leak has occurred in a part of your code, you can take a snapshot of the memory state before and after that section, and then use _CrtMemDifference to compare the two states:
?
123456 |
_CrtMemCheckpoint( &s1 ); // memory allocations take place here _CrtMemCheckpoint( &s2 ); if ( _CrtMemDifference( &s3, &s1, &s2) ) _CrtMemDumpStatistics( &s3 ); |
As the name implies,_crtmemdifference compares the two memory states (S1 and S2) to produce a result of the difference between the two states (S3). Placing _CrtMemCheckpoint calls at the beginning and end of a program and using _crtmemdifference to compare results is another way to check for memory leaks. If a leak is detected, you can use the _crtmemcheckpoint call to divide the program and locate the leak using binary search techniques.
As the above example program we can do this to locate the exact place to call GetMemory:
View Code
When debugging, the program outputs the following results:
This means there is a memory leak between S1 and S2!!! If GetMemory is not called between S1 and S2, then there will be no information output.
3. Memory leak detection under Linux platform
In the above we introduced, vs in the code "contains Crtdbg.h, the malloc and free functions are mapped to their debug version, namely, _malloc_dbg and _free_dbg, these two functions will track memory allocation and deallocation." This mapping occurs only in the debug version (where _DEBUGis defined). The release version uses the normal malloc and free functions. "is a hook for malloc and free to record memory allocation information.
Linux below also has the same principle method--mtrace,http://en.wikipedia.org/wiki/mtrace. Method similar, I do not specifically describe, participate in the given link. This section I mainly introduce a very powerful tool valgrind. As shown in the following:
As shown, you know:
==6118== bytes in 1 blocks is definitely lost in loss record 1 of 1
==6118== at 0x4024f20:malloc (vg_replace_malloc.c:236)
==6118== by 0x8048724:getmemory (char*, int.) (In/home/netsky/workspace/a.out)
==6118== by 0x804874e:main (in/home/netsky/workspace/a.out)
Is the memory leak caused by getmemory in main, which is called by malloc, causing a leak of 100 bytes of memory.
Things to notice:
? There is a IoT of information in each error message; Read it carefully.
? The 6118 is the process ID; It ' s usually unimportant.
? The. RST line ("Heap Summary") tells your what kind of error it is.
? Below rst line is a stack trace telling where the problem occurred. Stack traces can get quite large, and be
Confusing, especially if you is using the C + + STL. Reading them from the bottom up can help.
? The code addresses (eg 0x4024f20) is usually unimportant, but occasionally crucial for tracking down weirder
Bugs.
The stack trace tells you where the leaked memory is allocated. Memcheck cannot tell the memory leaked,
Unfortunately. (Ignore the "vg_replace_malloc.c", that's an implementation detail.)
There is several kinds of leaks; The most important categories is:
? "De?nitely Lost": Your program is leaking memory--? x it!
? "Probably lost": Your program was leaking memory, unless you ' re doing funny things with pointers (such as moving
them to point to the middle of a heap block)
For valgrind use, please see the manual http://valgrind.org/docs/manual/manual.html.
4. Summary
In fact, the cause of memory leaks can be summarized as: Call the Malloc/new and other memory applications, but the lack of corresponding free/delete, in short, malloc/new than the number of free/delete. We need to pay attention to this in programming, to ensure that each malloc has a corresponding free, each new has a corresponding deleted!!! Usually want to develop such a good habit.
To avoid a memory leak, you can summarize the following points:
- Programmers should develop good habits to ensure that malloc/new and Free/delete match;
- The key principle of detecting a memory leak is to check whether Malloc/new and Free/delete match, and some tools are the same principle. To do this, you can use a macro or a hook to add a layer between the user program and the runtime to record memory allocations.
C + + memory leak and detection