Reputation: 641
VB.NET 2010, Framework 3.5
Trying to figure out how to get the memory back after I'm done with a list of a custom object type. I know forcing the list out of scope will reallocate the memory it's using but I need a way of doing it pragmatically. Does anyone know how to do this?
Public Class List_Of_T_Test
Private MyTestClass As New List(Of TestClass)
Private Sub List_Of_T_Test_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Const LIST_COUNT As Integer = 5000000
Dim Count As Integer = 0
MsgBox("Note 'PF usage' on Windows Task Manager 'before the 5m list' is created")
Do Until Count > LIST_COUNT ' 5 million iterations
MyTestClass.Add(New TestClass With {.Value1 = CStr(Count), .Value2 = CStr(Count + 1)})
Count = Count + 1
Loop
MsgBox("Note 'PF usage' on Windows Task Manager 'after the 5m list' was created")
DestroyMyTestClassList()
MsgBox("When flow arrives here, I need MyTestClass to be gone, all memory to have been reallocated, or close to where it was before the list was created")
End Sub
Private Sub DestroyMyTestClassList()
' Does anyone know what code to put here, code that would totally destroy
' the MyTestClass and the 5 million items in it, reallocate the memory used
' by the list Of(T) MyTestClass
' MyTestClass.Clear() ' Doesn't work ??
' MyTestClass = Nothing ' Doesn't work ?
End Sub
Public Class TestClass
Public Property Value1 As String
Public Property Value2 As String
End Class
End Class
I understand the idea of letting it go out of scope but I have to tell you, I tried Disposing the form, closing it etc and loading a separate form and the memory still didn't come back. I guess GC hadn't got around to its collection business or something. I'll have to watch the GC work a bit longer I guess
This feller by the name of Jods was curious as to why I wanted to do this programmatically. The type of work I'm doing, creating copious types of custom lists that will be very dynamic in nature, that I need a way to destroy them and rebuild them with certainty that the old stuff is gone. These apps run non-stop for weeks sometimes so . . I need to pay close attention to memory and whatnot.
If of any interest to anyone, see code below that seems to reallocate the memory from a list of objects
Public Class List_Of_T_Test
Private MyTestClass As New List(Of TestClass)
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Const LIST_COUNT As Integer = 5000000
Dim Count As Integer = 1
Do Until Count > LIST_COUNT ' 5 million iterations
MyTestClass.Add(New TestClass With {.Value1 = CStr(Count), .Value2 = CStr(Count + 1)})
Count = Count + 1
Loop
MsgBox(MyTestClass.Count.ToString)
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
' This seems to completely reallocate the memory, paste this into a form's code,
' add two buttons, click button1 once, or few times while watching the
' 'Windows Task Manager' PF Usage.
' Then Click button2 once and the memory spike levels off, it all comes back
MyTestClass = New List(Of TestClass)
GC.Collect() ' ?
End Sub
Private Class TestClass
Public Property Value1 As String
Public Property Value2 As String
End Class
End Class
Upvotes: 0
Views: 2967
Reputation: 3214
When the .NET framework instantiates an object, it allocates memory for that object on the managed heap. The object remains on the heap until it's no longer referenced by any active code, at which point the memory it's using is "garbage," ready for memory deallocation by the .NET Garbage Collector (GC). Before the GC deallocates the memory, the framework calls the object's Finalize() method, but developers are responsible for calling the Dispose() method.
So, just call the Dispose() method of your object(s).
Upvotes: -1
Reputation: 4591
I'm very curious why you need a way to do it programatically. When your objects are not used anymore (all references are un-reachable / out of scope / or set to null), the memory is reclaimed by the next run of the garbage collector.
If you want to trigger a collection by code you should call GC.Collect(). If you have finalizers you might have to call GC.WaitForPendingFinalizers() and then GC.Collect() again.
Note that calling these methods is generally frown upon, so I'm curious about your case.
Upvotes: 2