vb.net 中的 Static 局部变量是否不适用于一次性对象?
Is Static local variable in vb.net unsuitable for disposable objects?
局部 Static
变量是否不能用于一次性对象?这种情况的主要问题是:Dispose()
可能永远不会被调用。
示例:
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
这种情况下,是否只有将局部静态变量转换为局部class变量(在Sub Dispose(disposing As Boolean)
中处理)?
是的,如果你想处理掉它们是不行的。
Static
局部变量编译为
- 在
Shared
过程中:
- 到
Shared
class 级别的字段变量
- 在非
Shared
实例方法中:
- 到 class 级别的实例字段变量
...哪个名称派生自方法名称和变量名称以确保它在每种类型中都是唯一的。
Shared
变量在应用程序的生命周期内永远不会被释放,因为您只能释放实例。当您调用 instance.Dispose
或使用 Using
语句时,实例变量会被释放。
但是 CLR 中的垃圾收集器不会(也不能)处理非托管对象。所以问题是你不能从 Dispose
中处理这些对象,因为它超出了局部变量的范围。因此,如果您需要清理 Dispose
中的非托管资源,则无法使用 Static
局部变量来执行此操作,因为您无法访问它们。
值得一读:
遗憾地说,在使用 VS2015 的 Memory Usage Tool 检查后,我可以确认静态实例 NOT GC'ed when closing/disposing 例如一个表单使用它们。
要测试它,请创建一个包含两个表单的项目。在 Form2 的 Form2_Load
事件中声明并向静态 List(Of Font)
添加一些字体。在 Form1_Load
中创建并显示 Form2 的实例。
使用 Debug->Performance and Diagnostics
菜单选项执行项目,使用 Memory Usage
行为。
您会弹出两个表单。
关闭 Form2。单击 Memory Usage Tool
window 中的 Force GC
按钮并拍摄内存快照。
关闭 Form1 以停止执行。
单击快照 1 中的 nnnn objects
link,将打开一个新的 window。取消选中 window.
右上角下拉按钮中的 Collapse small objects
在搜索框中输入 'font',您将看到内存中剩余的所有字体。
局部 Static
变量是否不能用于一次性对象?这种情况的主要问题是:Dispose()
可能永远不会被调用。
示例:
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
这种情况下,是否只有将局部静态变量转换为局部class变量(在Sub Dispose(disposing As Boolean)
中处理)?
是的,如果你想处理掉它们是不行的。
Static
局部变量编译为
- 在
Shared
过程中:- 到
Shared
class 级别的字段变量
- 到
- 在非
Shared
实例方法中:- 到 class 级别的实例字段变量
...哪个名称派生自方法名称和变量名称以确保它在每种类型中都是唯一的。
Shared
变量在应用程序的生命周期内永远不会被释放,因为您只能释放实例。当您调用 instance.Dispose
或使用 Using
语句时,实例变量会被释放。
但是 CLR 中的垃圾收集器不会(也不能)处理非托管对象。所以问题是你不能从 Dispose
中处理这些对象,因为它超出了局部变量的范围。因此,如果您需要清理 Dispose
中的非托管资源,则无法使用 Static
局部变量来执行此操作,因为您无法访问它们。
值得一读:
遗憾地说,在使用 VS2015 的 Memory Usage Tool 检查后,我可以确认静态实例 NOT GC'ed when closing/disposing 例如一个表单使用它们。
要测试它,请创建一个包含两个表单的项目。在 Form2 的 Form2_Load
事件中声明并向静态 List(Of Font)
添加一些字体。在 Form1_Load
中创建并显示 Form2 的实例。
使用 Debug->Performance and Diagnostics
菜单选项执行项目,使用 Memory Usage
行为。
您会弹出两个表单。
关闭 Form2。单击 Memory Usage Tool
window 中的 Force GC
按钮并拍摄内存快照。
关闭 Form1 以停止执行。
单击快照 1 中的 nnnn objects
link,将打开一个新的 window。取消选中 window.
右上角下拉按钮中的 Collapse small objects
在搜索框中输入 'font',您将看到内存中剩余的所有字体。