Search code examples
memory-managementvala

Is reusing a variable but memory not being released by the process considered a memory leak?


In Vala I have a TreeMultiMap from the Gee library created as a private variable of a class. When I use the tree multi map and fill it with data, the memory consumption of the process increases to 14.2 MiB. When I clear the tree multi map which is still the same variable and use it again, but add less data to it, the memory consumption of the process doesn't increase, but it doesn't decrease either. It stays at 14.2 MiB.

The code is as follows MultiMapTest.vala

using Gee;

private TreeMultiMap <string, TreeMultiMap<string, string> > rootTree;

public static int main () {
    // Initialize rootTree
    rootTree = new TreeMultiMap<string, TreeMultiMap<string, string> > (null, null);

    // Add data repeatedly to the tree to make the process consume memory
    for (int i = 0; i < 10000; i++) {
        TreeMultiMap<string, string> nestedTree = new TreeMultiMap<string, string> (null, null);
        nestedTree.@set ("Lorem ipsum", "Lorem ipsum");
        rootTree.@set ("Lorem ipsum", nestedTree);
    }

    stdout.printf ("Press ENTER to clear the tree...");
    // Wait for the user to press enter
    var input = stdin.read_line ();

    // Clear the tree
    rootTree.clear ();

    stdout.printf ("Press ENTER to continue and refill the tree with less data...");
    // Wait for the user to press enter
    input = stdin.read_line ();

    // Refill the tree but with much less data
    for (int i = 0; i < 10; i++) {
        TreeMultiMap<string, string> nestedTree = new TreeMultiMap<string, string> (null, null);
        nestedTree.@set ("Lorem ipsum", "Lorem ipsum");
        rootTree.@set ("Lorem ipsum", nestedTree);
    }

    stdout.printf ("Press ENTER to quit...");
    // Wait for the user to press enter
    input = stdin.read_line ();
    return 0;
}

Compiled with valac --pkg gee-0.8 -g MultiMapTest.vala

Is this considered a memory leak? If so, is there any way to properly approach the situation such as that memory gets released to the OS once the tree multi map is cleared even if it involves using other data structures?

I used valgrind, but could not detect any memory leaks. My take on it is that once memory is allocated for the TreeMultiMap variable, unless the variable goes out of scope, the program will keep that memory allocated until the end of its lifetime instead of releasing it back to the operating system. Even if the TreeMultiMap is emptied.


Solution

  • This has little to do with Vala and more to do with the way UNIX programs deal with memory.

    When a program starts, the UNIX kernel allocates memory for the program itself, the stack, and an area called the heap where memory can be dynamically allocated by the program. From the UNIX kernel's perspective, the heap is a large chunk of memory and the program can request more using sbrk.

    In C, and most other languages, you need small chunks of memory quite often. So, the C standard library has a code to do memory allocation via malloc and free. When you allocate memory using malloc, it takes it out of the free space it has in the heap. When you free it, it can be reused by a later malloc. If there isn't enough memory, malloc will call sbrk to get the program more memory. No matter how much you free, the C standard library will not give memory back to the kernel until he program ends.

    Valgrind and Vala are talking about memory leaks where you malloc without free. ps or top see the total memory that was allocated by sbrk.

    That means if you malloc a large chunk of memory, then free it, Valgrind will show it as correctly freed and it is available to your program for reuse, but the kernel still considers it in use by the program.