During my STSdb4 implementation on large data sets, I've noticed a rather simple but important note on using the StorageEngine. As it's obvious StorageEngine is there to hold large amount of data either in RAM or disk.

The usual usage of a StorageEngine is like below:
static void Main(string[] args) 
{
using (IStorageEngine infoEngine = STSdb.FromHeap(new Heap(new FileStream("info.stsdb4", FileMode.OpenOrCreate), true)))
{
// do some insert and lookup

infoEngine.Commit();
infoEngine.Close();

}

// At this point Memory is held by StorageEngine and is not released yet

Console.ReadKey();

}
You may think that after the using statement, the used memory by StorageEngine will be released since using will call Dispose on the object. That's true and the StorageEngine object will be disposed upon leaving the using block. But there's a missing point here. If you take a memory snapshot of the app just before the Console.ReadKey() line, you'll see the following snapshot (taken using ANTS Memory Profiler).

The point is that, Local variables is one the GC Roots (c# - What is a "rooted reference"? - Stack Overflow) and so as it's obvious in attached picture, the infoEngine variable is a GC Root and will hold all the its allocated children objects (in my sample wasting 27 MB of memory).

The easy solution to have proper memory counting would be to make the code working with engine wrapped in a simple method like this:

static void Main(string[] args) 
{

DoDBOperations();

// At this point Memory is released

Console.ReadKey();

}

public static void DoDBOperations()
{

using (IStorageEngine infoEngine = STSdb.FromHeap(new Heap(new FileStream("info.stsdb4", FileMode.OpenOrCreate), true)))
{
// do some insert and lookup

infoEngine.Commit();
infoEngine.Close();

}

}