Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Saturday, July 30, 2016 1:22 PM
I'm reading a file, where I have stored 2 Lists, using the binary serialization. When I try to read them one by one, I try to overwrite a List object.
using (Stream stream = File.Open("E:\\listfile.txt", FileMode.Open))
{
var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
for (int i = 0; i < 2; i++)
{
List<int> li3 = (List<int>)bformatter.Deserialize(stream);
Console.WriteLine(li3.Count + " " + li3.ElementAt(500));
}
}
The problem is, after the first read, memory usage of my app is about 7MB. And after the second it is about 11MB.
How can I prevent that? How can I just have my app load memory needed for only one list at a time?
All replies (5)
Sunday, July 31, 2016 8:30 PM âś…Answered | 1 vote
On your first read, memory for the list is allocated on the heap, and a reference to that allocation is stored in the local variable. On te second read, a new list is allocated on the heap, and the local variable that referenced the previous memory on the heap is destroyed. Therefore, the old list in the heap becomes unreachable. In some other environments, that memory for the old list would be deallocated at this time. Not so in C#. As long as there is no memory pressure (meaning that you still have plenty of memory and it is not needed for anything else), the unreachable allocation is left alone and the runtime doesn't bother to free it. When the memory is needed, the Garbage Collector is triggered and it frees unreachable objects from the heap. This pass of the Garbage Collector may not happen for a long time, possibly only when your program terminates.
If you want to force a Garbage Collection, you can do it by a call to GC.Collect(). It is not recommended that you do this in a production application, but you may use that instruction for experimenting during development time.
Sunday, July 31, 2016 9:47 PM
Memory allocation is not usualy a cause for worry. The Garbage collection tries to minimise it's overhead. Idealy that means it only runs once - during application closure. So unless they is actuall memory contention, the memory footprint will just keep increasing. As long as you do not have any reference leaks and nothing needs to be disposed off, nothing bad will come from that.
See these articles for a more indept explanation and common pitfalls when measuring performance/memory:
http://www.itwriting.com/dotnetmem.php
Which is faster? | Fabulous Adventures In Coding
Garbage Collection - Pros and Limits
Monday, August 1, 2016 1:26 PM
Thanks for the concern. Can you suggest me a better way to do this? I am not yet able to proceed. Since the List is not disposable, I just cannot think of anything else.
Monday, August 1, 2016 1:39 PM
Why are you not able to proceed?
As others have said, the use of memory is simply a side effect of the way the .NET environment and its garbage collection process works. It keeps hold of the memory if it can in case it needs it again; the memory will be released if and when necessary (i.e. memory is running low and/or something else needs it). This is more efficient than having to constantly de-allocate and re-allocate memory blocks.
In general, as long as you ensure you are disposing of all disposable objects (as you are) then there is nothing to worry about. Let .NET just do its thing!
See the comments and links posted by Alberto and Christopher84 above.
Monday, August 1, 2016 5:45 PM
Since the List is not disposable, I just cannot think of anything else.
Note that even if the list was disposable, it would still not change anything. The IDisposable interface is meant for freeing non-managed resources. The memory allocated in the managed heap does not get freed by Dispose(). You would still need to wait for the GC to free it. As others mentioned before, you do not need to worry about this under ordinary circumstances. This will be automatically handled by the runtime when it becomes necessary.