How to Detect/Avoid Memory Leaks in Your (Unmanaged) Code

Clean up of memory leak in unmanaged code

No way, unless of course you can modify and fix the C++ code, but probably this is not an option. I had the same problem in the past, solution is host the leaking code in a process ( note: an app domain is not enough ) and shut down periodically that process. Use some IPC technique to comunicate with that process instance. You can optional create a pool of two of that process to apper reactive even when you need to shutdown a process, so you can easily switch to the other instance, already running.

How to find memory leak in a C++ code/project?

Instructions

Things You'll Need

  • Proficiency in C++
  • C++ compiler
  • Debugger and other investigative software tools

1

Understand the operator basics. The C++ operator new allocates heap memory. The delete operator frees heap memory. For every new, you should use a delete so that you free the same memory you allocated:

char* str = new char [30]; // Allocate 30 bytes to house a string.

delete [] str; // Clear those 30 bytes and make str point nowhere.

2

Reallocate memory only if you've deleted. In the code below, str acquires a new address with the second allocation. The first address is lost irretrievably, and so are the 30 bytes that it pointed to. Now they're impossible to free, and you have a memory leak:

char* str = new char [30]; // Give str a memory address.

// delete [] str; // Remove the first comment marking in this line to correct.

str = new char [60]; /* Give str another memory address with
the first one gone forever.*/

delete [] str; // This deletes the 60 bytes, not just the first 30.

3

Watch those pointer assignments. Every dynamic variable (allocated memory on the heap) needs to be associated with a pointer. When a dynamic variable becomes disassociated from its pointer(s), it becomes impossible to erase. Again, this results in a memory leak:

char* str1 = new char [30];

char* str2 = new char [40];

strcpy(str1, "Memory leak");

str2 = str1; // Bad! Now the 40 bytes are impossible to free.

delete [] str2; // This deletes the 30 bytes.

delete [] str1; // Possible access violation. What a disaster!

4

Be careful with local pointers. A pointer you declare in a function is allocated on the stack, but the dynamic variable it points to is allocated on the heap. If you don't delete it, it will persist after the program exits from the function:

void Leak(int x){

char* p = new char [x];

// delete [] p; // Remove the first comment marking to correct.

}

5

Pay attention to the square braces after "delete." Use delete by itself to free a single object. Use delete [] with square brackets to free a heap array. Don't do something like this:

char* one = new char;

delete [] one; // Wrong

char* many = new char [30];

delete many; // Wrong!

6

If the leak yet allowed - I'm usually seeking it with deleaker (check it here: http://deleaker.com).

dealing with an unmanaged dll with a memory leak

The way you describe it, the dll is allocating non-managed memory. This kind of memory will not be impacted by the act of unloading an appdomain, unfortunately, as you've already found out.

You got a couple of options, but I don't think any of them are appealing:

  1. You can keep using the dll in your main application. You can advise your users/clients that they need to have lots of memory available, but will need to restart the application from time to time. You would probably want to detect out-of-memory conditions before the program actually starts crashing, to gently prod the user to restart it, instead of just crashing hard with an exception.
  2. You can try to dig into the data structures of the dll. If the dll is actually changing (ie. new versions are coming out), I would strongly suggest you lean hard on the author to get the memory leak fixed. However, this seems unlikely since I'm pretty sure the leak would be fixed if a new version came out. As such, tying your code directly to the innards of that dll might be a solution. Having access to the actual pointer that references the unmanaged memory might allow you to manually free it as you see fit.
  3. You can isolate the problem to a separate process. More on that below.
  4. You could reimplement the functionality of the dll.

There might be a 5th or a 6th option here, but think the above 4 covers the things I came up with off the top of my head.

About isolating it into a separate process, here's what I would try to do first:

I would spin up a process, and pump requests to it using the fastest intra-process communication channel you can find. Pipes seems a good fit, or memory-mapped files.

You would then, in that separate process, detect the out-of-memory condition, hopefully a bit early, so that you could advise the main program that it should think about spinning up a replacement process.

The main process could then do that, but instead of waiting for that other process to fully spin up, it could keep pumping a few more requests to the soon-to-be-dead instance, filling it up a bit more, before switching over to the new instance and asking the old to terminate.

This would minimize the downtime at the expense of temporarily having an extra process alive during transitions.

All of this depends, a lot, on the actual scenarios you have. If you need to call this dll 100s or 1000s of times a second, doing intra-process communication might not be doable in any case.

How to monitor memory usage for managed/unmanaged code

AQTime will instrument both managed and unmanaged code. I have used it successfully to find memory leaks in managed/unmanaged project.

Memory leak detection for mixed mode projects: managed, unmanaged and native

In .NET even if you use managed objects there may be something that never get disposed (check some examples here: Memory Leak in C#).

About the native part, you may use two different approaches:

  • use a different memory profiler software, many listed here: Is there a good Valgrind substitute for Windows?

  • change your sources to use debug malloc/new and to print where in the code the allocations are done: http://www.flipcode.com/archives/Detecting_Memory_Leaks.shtml

Avoid memory leak in c# client of a unmanaged DLL with memory leak

According to my theory, this changes nothing.
In C#/managed, nothing much different will happen than if you'd load a DLL into a native program. The DLL will allocate heap memory and since that resource belongs to the process it will persist, even if the DLL is unloaded.

Things would change if you'd have a purely managed DLL. You could then load it into an app domain and dispose the DLL alltogether with the App-Domain...

So solutions?
The hard way would be similar to the 64-Bit Process with 32-Bit DLL Problem.
Create a separate process, load the DLL and do remote calls. This is cumbersome but if it is only a vew calls, it may be worth it.

Other:
Not that I know of but fixing the DLL's code.



Related Topics



Leave a reply



Submit