miroxlav
miroxlav

Reputation: 12194

Is Static local variable in vb.net unsuitable for disposable objects?

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

Answers (2)

Ivan Ferrer Villa
Ivan Ferrer Villa

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

Tim Schmelter
Tim Schmelter

Reputation: 460138

Yes, they are a no-go if you want them to be disposed.

Static local variables are compiled to

  • in a Shared procedure:
    • to Shared field variables at class level
  • in a non-Shared instance method:
    • to instance field variables at class level

...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

Related Questions