Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yet another Memory Leak Issue (memory is still gone when program terminates)- C program on SLES

I run my C program on Suse Linux Enterprise that compresses several thousand large files (between 10MB and 100MB in size), and the program gets slower and slower as the program runs (it's running multi-threaded with 32 threads on a Intel Sandy Bridge board). When the program completes, and it's run again, it's still very slow.

When I watch the program running, I see that the memory is being depleted while the program runs, which you would think is just a classic memory leak problem. But, with a normal malloc()/free() mismatch, I would expect all the memory to return when the program terminates. But, most of the memory doesn't get reclaimed when the program completes. The free or top command shows Mem: 63996M total, 63724M used, 272M free when the program is slowed down to a halt, but, after the termination, the free memory only grows back to about 3660M. When the program is rerun, the free memory is quickly used up.

The top program only shows that the program, while running, is using at most 4% or so of the memory.

I thought that it might be a memory fragmentation problem, but, I built a small test program that simulates all the memory allocation activity in the program (many randomized aspects were built in - size/quantity), and it always returns all the memory upon completion. So, I don't think that's it.

Questions:

  1. Can there be a malloc()/free() mismatch that will lose memory permanently, i.e. even after the process completes?

  2. What other things in a C program (not C++) can cause permanent memory loss, i.e. after the program completes, and even the terminal window closes? Only a reboot brings the memory back. I've read other posts about files not being closed causing problems, but, I don't think I have that problem.

  3. Is it valid to be looking at top and free for the memory statistics, i.e. do they accurately describe the memory situation? They do seem to correspond to the slowness of the program.

  4. If the program only shows a 4% memory usage, will something like valgrind find this problem?

like image 722
Keith Hogan Avatar asked Feb 20 '23 05:02

Keith Hogan


1 Answers

Can there be a malloc()/free() mismatch that will lose memory permanently, i.e. even after the process completes?

No, malloc and free, and even mmap are harmless in this respect, and when the process terminates the OS (SUSE Linux in this case) claims all their memory back (unless it's shared with some other process that's still running).

What other things in a C program (not C++) can cause permanent memory loss, i.e. after the program completes, and even the terminal window closes? Only a reboot brings the memory back. I've read other posts about files not being closed causing problems, but, I don't think I have that problem.

Like malloc/free and mmap, files opened by the process are automatically closed by the OS.

There are a few things which cause permanent memory leaks like big pages but you would certainly know about it if you were using them. Apart from that, no.


However, if you define memory loss as memory not marked 'free' immediately, then a couple of things can happen.

  1. Writes to disk or mmap may be cached for a while in RAM. The OS must keep the pages around until it synchs them back to disk.
  2. Files READ by the process may remain in memory if the OS has nothing else to use that RAM for right now - on the reasonable assumption that it might need them soon and it's quicker to read the copy that's already in RAM. Again, if the OS or another process needs some of that RAM, it can be discarded instantly.

Note that as someone who paid for all my RAM, I would rather the OS used ALL of it ALL the time, if it helps in even the smallest way. Free RAM is wasted RAM.


The main problem with having little free RAM is when it is overcommitted, which is to say there are more processes (and the OS) asking for or using RAM right now than is available on the system. It sounds like you are using about 4Gb of RAM in your processes, which might be a problem - (and remember the OS needs a good chunk too. But it sounds like you have plenty of RAM! Try running half the number of processes and see if it gets better.

Sometimes a memory leak can cause temporary overcommitment - it's a good idea to look into that. Try plotting the memory use of your program over time - if it rises continuously, then it may well be a leak.

Note that forking a process creates a copy that shares the memory the original allocated - until both are closed or one of them 'exec's. But you aren't doing that.

Is it valid to be looking at top and free for the memory statistics, i.e. do they accurately describe the memory situation? They do seem to correspond to the slowness of the program.


Yes, top and ps are perfectly reasonable ways to look at memory, in particular observe the RES field. Ignore the VIRT field for now. In addition:

To see what the whole system is doing with memory, run:

vmstat 10

While your program is running and for a while after. Look at what happens to the ---memory--- columns.

In addition, after your process has finished, run

cat /proc/meminfo

And post the results in your question.

If the program only shows a 4% memory usage, will something like valgrind find this problem?

Probably, but it can be extremely slow, which might be impractical in this case. There are plenty of other tools which can help such as electricfence and others which do not slw your program down noticeably. I've even rolled my own in the past.

like image 189
Alex Brown Avatar answered Apr 28 '23 15:04

Alex Brown