1

I have a C application which processes large amount of data (100+ KB). I am using malloc() to allocate the memory needed.

(char*)malloc(argLen + 18 + 2)

And after the execution, I use free to release the allocated memory.

I understand that the free'd memory is not returned to the OS due to some reasons. My question is when I run the program again, instead of reusing the allocated memory, it just keeps on increasing the memory usage of my application.

Edit: I am sorry for the confusion. The process is a WebSocket service. And it will not terminate unless the it is intentionally stopped. Does this mean that the process will keep on increasing its memory usage and will not let go of the allocated memory unless I restart it manually?

Ronnie
  • 69
  • 1
  • 7
  • *"I understand that the free'd memory is not returned to the OS due to some reasons."* - Why do you believe that? – klutt Nov 17 '17 at 10:34
  • 3
    `free()` does not necessarily return the memory to the os immediately, but after process _termination_, all memory used by that process should be available again instantly. – Ctx Nov 17 '17 at 10:34
  • 1
    Is that a question ("does memory usage increase when running for a prolonged time?") or is that an observation you made? – datenwolf Nov 17 '17 at 10:35
  • 2
    Lets see the rest of the code?... And can you tell us how you are determining the memory is increasing? – Joe Nov 17 '17 at 10:35
  • 4
    BTW - You do not need to cast `malloc` in C - It is bad practice - see https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Ed Heal Nov 17 '17 at 10:36
  • 2
    @klutt: Because that's how memory allocators work. Allocating memory from the OS is a costly operation; faulting the pages even moreso. Usually the memory requirements of a process that does not leak memory will asymptotically grow toward some value. It makes a lot of sense to just keep around that much memory allocated from the OS and work entirely in that area. – datenwolf Nov 17 '17 at 10:38
  • If your process still has memory allocated to it, it has not terminated. If a process terminates, the OS will splat all memory allocated solely to that process. Unless you explicitly shared memory with another process, it's gone. – Martin James Nov 17 '17 at 10:41
  • 1
    @EdHeal there are pros and cons on casting the result of `malloc()`, a bunch of upvotes on a (unnecessarily) undifferentiated opinion does not change that. – Ctx Nov 17 '17 at 10:41
  • @datenwolf I know. I just wanted to know that OP has read about it. – klutt Nov 17 '17 at 10:48
  • 1
    Try using `GlobalAlloc` / `GlobalFree` instead of `malloc` / `free`. – i486 Nov 17 '17 at 11:22
  • Please see my edit. Thanks – Ronnie Nov 17 '17 at 11:54
  • @joe I observed the increase using Task Manager. Everytime I send a command, the memory usage keeps on increasing even though I already freed the previous – Ronnie Nov 17 '17 at 11:57
  • @Ctx The process will not terminate unless it is manually stopped or the machine is restarted. Does this mean that the process will keep increasing its memory usage while it is still running? – Ronnie Nov 20 '17 at 01:14
  • Did you just cast the return of `malloc`? – lost_in_the_source Nov 20 '17 at 01:18
  • Yes. I am casting the return of malloc to char* – Ronnie Nov 20 '17 at 01:33
  • @Ronnie In C, it is not necessary, and even harmful, to do that – lost_in_the_source Dec 13 '17 at 02:39

1 Answers1

4

I understand that the free'd memory is not returned to the OS due to some reasons.

What happens to the memory after calling free is implementation dependent. You tell the operating system that you're done with it. It may or may not release it. One reason for not releasing it is that it can be costly to allocate memory, and if the program asks for more memory the OS can just give back the same memory again.

My question is when I run the program again, instead of reusing the allocated memory, it just keeps on increasing the memory usage of my application.

Nope. As soon as your program terminates all of its allocated memory will be released. Or at least it should. Nevertheless, one could say that "it is not of your business".

I made a simple C program. It doesn't have any error checks, but you can use it to observe the behavior of your program while running it. The code for filling the array with random values and the code for printing it is solely there to make sure that nothing gets optimized away.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    int *ptr;
    int size;
    char c='a';
    srand(time(NULL));

    while(c!='q')
    {
        printf("a - allocate memory\n");
        printf("f - free memory\n");
        printf("p - print array\n");
        printf("q - quit\n");
        printf("Choose: ");
        scanf(" %c", &c);
        if(c=='q')
            break;
        else if(c=='a') {
            printf("Size : ");
            scanf(" %d", &size);
            ptr=malloc(size * sizeof(*ptr));
            for(int i=0; i<size; i++)
                ptr[i]=rand();
        }
        else if (c=='f')
            free(ptr);
        else if(c=='p') {
            for(int i=0; i<size; i++)
                printf("%d", ptr[i]);
        }
    }
}

While using it I was watching the process with top -p<PID> and it looked like this:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND     
28601 klutt     20   0    4172    692    616 S   0.0  0.0   0:00.00 a.out    

When I allocated and freed memory it sometimes showed and sometimes not. It made a difference more frequently if I specified a large size. And yes, I know you specified Windows and I used a Linux command, but I'm pretty sure you can find equivalent tools for analyzing a process in Windows.

klutt
  • 30,332
  • 17
  • 55
  • 95