|First, are you looking in Task Manager to determine this?
It's lying to you. It's not showing you how much memory your app is taking. It's showing you how much is RESERVED for your app.
You have to understand how memory allocations work in the .NET CLR and how it relates to Windows memory management. The .NET CLR manages the "Managed Heap", which is what your app sees (and Task Manager does NOT). When your app allocates an object, it's allocated on the Managed Heap. When an object is freed, that memory goes back into the Managed Heap, NOT BACK TO WINDOWS!
Just because your code is not using an object anymore, that does NOT mean the memory it occupies is immediately returned to the Managed Heap!
When more objects need to be allocated, it's faster for the CLR to allocate from the Managed Heap than it is for it to find out there's not enough enough heap left, go to Windows to get another block of memory, add it to the heap, then allocate your object.
This is why you're seeing what's RESERVED for your app.
When the CLR feels the conditions are right, it cleans up the managed heap, moving objects around and freeing up objects that don't have a reference being held anymore, returning that freed memory back to the Managed Heap. This is called Garbage Collection.
When Windows needs more memory, it asks the .NET CLR for whatever it can free up. If there's sufficient space on the Managed Heap, it'll shrink the size of the heap and return that freed memory back to Windows. If your code quickly allocats lots of objects and frees them, this can give the illusion of a memory leak.