我一直在问自己很长一段时间,当确切的对象和变量超出范围并被垃圾收集时。在这方面,参考和价值类型之间的区别也是如此。
例如,如果我使用
Private Sub Foo()
Dim ob as Integer = 1
End Sub
我的理解是,当Sub运行并且相关内存再次被释放时,变量超出范围。我认为这与引用相同。但是,我可以做以下
Private Sub Foo()
Dim frm1 as New Form1
frm1.Show() 'Edit made here!
End Sub
并打开相关表格,即使子表格立即结束也是如此。因此,似乎存在以某种方式保持打开的引用,因此不会丢弃新的表单实例。也许表格有一些特别之处。 但是其他一些随机物呢?
Private Sub Foo()
Dim ob as New MyRandomClass
End Sub
此对象是否会像表单一样持久存在?
有人可以了解范围的细节以及变量,对象和表格之间的差异(在我看来,与C#相比,在VB.net中并不是非常简单)。
答案 0 :(得分:3)
在.NET中,了解value types and reference types之间的区别非常重要。值类型主要是在堆栈上分配的基本类型。退出方法后,将释放此内存。第一个示例就是这种情况(Integer是值类型)。
相比之下,类是引用类型。这适用于表单和MyRandomClass
。对于引用类型,内存在托管堆上分配。仅在堆栈上分配对指向堆上位置的内存的引用。如果对堆上对象的所有引用都超出范围,则堆上的内存也会在稍后的时间由Garbage Collector释放。
这是您的第3个示例中发生的事情:您在堆上分配一个对象,其中有一个名为ob
的引用指向它。在方法结束时,将释放引用ob
,但堆上的对象仍将存在,直到垃圾收集器释放它为止。
然而,你的第二个样本确实是一个特例。您创建了Form1
的新实例,并将引用存储在frm1
中。调用Show
时,表单将成为应用程序用户界面的一部分。由于它是非模态形式,它会显示在屏幕上,但是应用程序的执行不会等到表单关闭。应用程序的用户界面线程用于处理表单的消息,直到它关闭为止。因此,虽然最初用于创建表单的表单已经超出范围,但还有其他一些对表单的引用。表单关闭后,内存将被释放,因为它不再有活动引用。