Reputation: 12194
Are local Static
variables a no-go for disposable objects? The main problem with this case: Dispose()
might never get called.
Example:
Sub DrawText(text As String, fontFamily As Font)
Static cachedFont As Font = Nothing
If cachedFont Is Nothing OrElse fontFamily <> cachedFont.Family Then
cachedFont = New Font(fontFamily)
EndIf
'now draw text using cachedFont
End Sub
Is such cases, is the only way to convert local static variable into local class variable (which is being disposed in Sub Dispose(disposing As Boolean)
)?
Upvotes: 4
Views: 639
Reputation: 2158
Sad to say it, after checking with VS2015's Memory Usage Tool I can confirm that Static instances are NOT GC'ed when closing/disposing for example a form using them.
To test it create a project with two forms. In Form2's Form2_Load
event declare and add some fonts to a Static List(Of Font)
. In Form1_Load
create and show an instance of Form2.
Execute the project using Debug->Performance and Diagnostics
menu option, use Memory Usage
behavior.
You'll get both forms popping up.
Close Form2. Click Force GC
button in Memory Usage Tool
window and take a memory snapshot.
Close Form1 to stop execution.
Click nnnn objects
link in Snapshot 1, a new window will open. Uncheck Collapse small objects
in upper right dropdown button of that window.
Type 'font' in search box and you'll see all those Fonts remaining in memory.
Upvotes: 1
Reputation: 460138
Yes, they are a no-go if you want them to be disposed.
Static
local variables are compiled to
Shared
procedure:
Shared
field variables at class level Shared
instance method:
...which name is derived from the method name and the variable name to ensure that it's unique per type.
The Shared
variables are never be disposed for the lifetime of an application because you can dispose only instances. The instance variables are disposed when you call instance.Dispose
or use the Using
-statement.
But the garbage collector in the CLR does not (and cannot) dispose of unmanaged objects. So the problem is that you can't dispose these objects from Dispose
because it's out of scope as local variable. So if you need to clean up unmanaged resources in Dispose
you can't do that with Static
local variables because you can't access them.
Worth reading:
Upvotes: 2