dev*_*747 6 c# garbage-collection
在Joseph Albahari的书中简要介绍了C#5.0,我找到了这个
一旦你传递了最后一个变量使用的代码行,它就会说它所引用的对象有资格进行垃圾收集(即如果没有其他变量持有对该对象的引用).
但是根据UC Berkley的这个讲座,只要对象上存在对象的引用,它就不会被垃圾回收.我的理解是,在方法返回之前,变量保留在堆栈上.这意味着它引用的任何对象都是活动的,直到该方法返回.
这是本书中的错误还是java和.net垃圾收集的工作方式不同?
但是根据UC Berkley的这个讲座,只要对象上存在对象的引用,它就不会被垃圾回收.
你是对的.您缺少的是堆栈中不再存在引用.
对于在堆栈上构造对象的代码:
StringBuilder ref1 = new StringBuilder("object1");
Run Code Online (Sandbox Code Playgroud)
变量ref1存储在堆栈中,在某些内存位置:
0x403730:
Stack Pointer -> 0x40372C: pointer to ref1
0x403728: saved value of EBP
0x403724: saved value of return address
0x403720
Run Code Online (Sandbox Code Playgroud)
现在是下一行:
StringBuilder ref2 = new StringBuilder("object2");
Run Code Online (Sandbox Code Playgroud)
指向ref2要存储的指针在哪里?在堆栈上:是的.但是堆栈在哪里?在当然用于的相同内存位置ref1!:
0x403730:
Stack Pointer -> 0x40372C: pointer to ref2
0x403728: saved value of EBP
0x403724: saved value of return address
0x403720
Run Code Online (Sandbox Code Playgroud)
简单地将另一个值压入堆栈将是愚蠢的:
Stack Pointer -> 0x403730: pointer to ref2
0x40372C: pointer to ref1
0x403728: saved value of EBP
0x403724: saved value of return address
0x403720
Run Code Online (Sandbox Code Playgroud)
这将是愚蠢的,因为ref1不再需要了.
这就是为什么ref1有资格进行垃圾收集的原因:不再有任何引用.
这本书是对的.
在.NET中,垃圾收集器具有代码中使用变量的位置的信息,并且一旦它未使用,该对象就有资格进行垃圾收集.
(但是,如果运行附加了调试器的代码,则垃圾收集器会更改行为.它会保留变量整个范围的对象,而不仅仅是使用变量的位置,以便可以在调试器中调查对象. )