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.
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.