|
|
1
21
垃圾收集器依赖于信息
同样,在代码中,由于不再使用对象变量,gc可以自由地收集它们。weakreference不会阻止这一点,事实上,这是一个wr的全部要点,允许您保留对对象的引用,而不会阻止它被收集。 有关案件 WeakReference 对象在msdn的一行描述中进行了很好的总结:
weakreference对象不是垃圾收集的,因此您可以安全地使用它们,但是它们引用的对象只剩下wr引用,因此可以自由收集。 当通过调试器执行代码时,变量在作用域中被人为地扩展到其作用域结束为止,通常是在声明它们的块的末尾(如方法),这样您就可以在断点处检查它们。 有一些微妙的事情要发现。请考虑以下代码:
在发布模式下,在未附加调试程序的情况下执行,输出如下: The value of Value: 15 Test collected Leaving Test.Execute
这样做的原因是,即使您仍然在与测试对象相关联的方法中执行,在请求GC执行它时,也不需要任何实例引用来测试(不引用
如果你不知道的话,这会有一些讨厌的副作用。 考虑以下类别:
此时,如果测试在获取非托管句柄的副本后不使用任何实例数据,该怎么办?如果GC现在在我写“危险”的地方运行呢?你看到这是要去哪里吗?当GC运行时,它将执行终结器,该终结器将从仍在执行的测试中提取对非托管资源的访问。
非托管资源,通常通过
换句话说,我们在局部变量中保留对句柄的引用对GC来说是毫无意义的,它只注意到没有剩余的实例引用,因此认为可以安全地收集对象。 如果course假定不存在对仍被视为“活动”的对象的外部引用,则会出现这种情况。例如,如果上面的类是从这样的方法中使用的:
那么你也有同样的问题。
(当然,您可能不应该这样使用它,因为它实现了IDisposable,所以您应该使用
编写上述方法的正确方法是强制GC在我们仍然需要它时不会收集我们的对象:
|
|
|
2
12
垃圾收集器从JIT编译器获取生存期提示。因此,它知道在gc.collect()调用中,没有更多可能的对局部变量的引用,因此可以收集它们。查看gc.keepalive()。 当附加了调试器时,将禁用JIT优化,并将生存期提示扩展到方法的末尾。使调试更简单。 我写了一个更详细的答案,你会发现 it here . |
|
3
0
我不是C专家,但我认为这是因为在生产中,您的代码在
不再有O1,O2结合。 编辑:这是一个名为常量折叠的编译器优化。 这可以通过或不通过JIT完成。 如果您有一种方法可以禁用JIT,但保持发布优化,那么您将拥有相同的行为。 人们应该注意以下几点:
这是钥匙。 附言:我也假设你理解weakreference的意思。 |
|
|
4
0
关于虚拟机垃圾如何收集资源的心智模型是不现实的简单。尤其是,假设变量和范围与垃圾收集有某种关联是错误的。
对。
JIT不需要不必要地保留引用,所以跟踪收集器在踢它时找不到引用,所以它收集了对象。 注意,其他答案已经表明,当事实是JIT实际上是 没有 将这些引用传递给GC,因为这样做没有意义。 |
|
codeforester · 测量GC暂停时间的最佳方法是什么? 7 年前 |
|
|
Venki WAR · 需要解释G1的并行完整GC 7 年前 |
|
|
Stephan_Berlin · 为什么CMS系列中的初始标记阶段 7 年前 |
|
|
Bonsaisteak · 为什么年轻一代需要三个区域来收集垃圾? 7 年前 |
|
|
goks · 如何清除熊猫的数据帧内存? 7 年前 |