Leak detection -- an introduction to session detection

Leak detection is very important to any decent software. If your program has a trivial flaw to leak small memory blocks each minutes, it will end up with crashing the user's system eventually by eating up all of the available memory.

There are many great leak detection tools in the world. BoundsChecker, AQTime (both can be used on C++ and Delphi program), FastMM (a memory manager with built-in leak detection), etc. Most of the tools have a limitation that they only report memory leak when the program exits.

Why "report on exit" is limited, less useful (but not useless) and less productive?
There are several reasons:

Reason 1: Leaks after exit are not very harmful on most operating system. Usually an OS such as Windows will reclaim all memory allocated by a program after the program exits. So if you allocate a global object to maintain the user settings, it will not hurt if not to free the object when the program exiting.
However, though it's not harmful, it's always a good habit to free the memory explicitly before your program exits.

Reason 2: Sometimes it's very difficult to clean memory before exiting. For example, many programmers think "Reason 1" is reasonable so they don't free the global objects, then if you use source code or library written by them, you can't free those objects unless you modify the library.
Another example, some complex objects relationship makes it very difficult to clean the memory. Suppose two objects are allocated at program startup, one is A and another is B. A depends on B and B depends on A. Freeing one of the two objects will cause another object crash. This is really a very bad OO design example, so you should firstly clear the dependence in your refactoring stage, but in memory leak detection stage, according to "Reason 1", such leak don't hurt, just leave it as it is to save your time.

Reason 3: "Report on exit" may report too many leaks. Maybe some leaks occur when the user opens a document, but some other leaks occur when the user is mailing a document. Those leaks have no connection with each other and should be detected respectively. But unfortunately, "Report on exit" can only dump all of them one time. You have to spend more time to distinguish them.

Reason 4: "Report on exit" is not always safe. Don't know how about you, at least I myself or many other programmers, like delaying freeing objects for performance purpose. Instead of freeing an object, I put it in to a global cache pool. I always remember clearing and freeing that cache pool when my program exits, yeah, I'm a good programmer :-), but in case I forget clearing that cache pool periodically (sometimes I'm not a good programmer), that pool will grow and grow until it crashes my program.
For such a case, the leak is very serious, but "Report on exit" can't report any leak because I clear and free the cache pool before exiting.

Reason 5: "Report on exit" can slightly slow down your debugging speed. At least you need to restart your program to debug and trace it after you reading the dump log. If your program needs 1 seconds to startup, you lose 1 seconds.

However, "Report on exit" is not fully useless. In fact it will be a memory leak safe guard for you. At the end of this article, I explained when we should use "Report on exit" rather than "session detection".

The better way: session leak detection

1, What's a session?
The term "session" here is used to define a period in which you perform serial actions on your program to expect some new memory is allocated and they should also be freed during the certain period.
To be simple, the program's state should be restored exactly same as the point that the session begins when the session ends.

If you are writing a text editor, a session can be like, open a document, edit it, save it, then close it. Because the document is closed, should no any leak related with the document occur.

2, How can session concept help you to detect leak?
Session concept can help leak detection in several points.

Point 1, Keep focus on only very few memory leaks. You can define a short period as a session, e.g, open-edit-save-close. Because the period is very short, only very few leaks occurs. Fewer things to do will always save time than more things to do.

Point 2, Easier to figure out the leaking source. Because the session period is very short, you can always know what happened during the period so it's much easier to find the leaking source.

Point 3, Reliable. Session detection is testing leaking dynamically in the program's run time life, it's more reliable than reporting static data when the program dies. See the "Reason 4" in above section.

Point 4, Low cost to test. You can only focus on the period you suspect leaking, you don't need to focus on the whole program life.
A low cost test cycle may look like,
Step 1, initial step. Test the whole program life (the whole life is a session). Find leaks.
Step 2, ask the developers to figure out which period causes those leaks, editing? mailing? or saving?
Step 3, define a small scope period which you suspect leaking, test again. If not find leaks, go to step 2 to tell the developers their guess is wrong. If find leaks, if you know the session period is short enough, go to step 4, otherwise, go to step 2 to reduce the scope.
Step 4, ask the developers to fix the leaks.
Step 5, go to step 3 to do regression test.

Point 5, Low cost to fix leak. It's very easy for developers to reproduce the leak because the leak will only occur in certain session.

3, The biggest disadvantage of session leak detection
The only and biggest disadvantage I can think is session leak detection can't recognize the re-created or re-allocated non-leak memory.
For example, we may often re-create some objects during a session. Image we have four time point, A, B, C, D. B to C is an atom session that can't be splitted to smaller sessions. We need an object X at point B, but we need the object be fresh when we reach B.
Then in point B we will write some code like,

procedure TimePointB;
begin
	if X <> nil then
		Free X;
	X = NewObject;
end;
In the session between point B to C, we free and then re-create an object X, so it's not a leak. However, because X is created during the session and still exist after the session, it will be marked as leak. It's wrong.

4, When is "report on exit" better than session detection
Please note all my above discussions are assuming your work is in debugging stage and your goal is to clean all memory leaks. At that stage, "session detection" will save you much time than "report on exit".
However, when your program is in a relative stable status and there are no serious leaks, "report on exit" can help you to ensure no any new leak is introduced. And in case you find any new leak, using "session detection" to fix that leak quickly.
Maybe we can get a conclusion: using "session detection" as a debug tool when you are debugging memory leak problems, and using "report on exit" as a memory leak safe guard on a daily basis. The good news is though the kernel concept in Denomo is "session detection", it also supports "report on exit".

Write a comment

  • Required fields are marked with *
  • Security Code is case sensitive, 'A' is different with 'a'.

If you have trouble reading the code, click on the code itself to generate a new random code.
Security Code: