![]() |
1
8
这只是代码中的一个错误:终结器不应该访问托管对象。 实现终结器的唯一原因是释放非托管资源。在这种情况下,您应该小心地执行 the standard IDisposable pattern . 使用此模式,可以实现受保护的方法“Protected Dispose(bool Disposing)”。当从终结器调用此方法时,它将清除非托管资源,但不尝试清除托管资源。 在您的示例中,您没有任何非托管资源,因此不应实现终结器。 |
![]() |
2
3
你所看到的完全是自然的。 不保留对拥有字节数组的对象的引用,因此对象(而不是字节数组)实际上是垃圾收集器可以收集的空闲对象。 垃圾收集器真的有那么强的攻击性。 因此,如果对对象调用一个方法,该方法返回对内部数据结构的引用,而对象的终结器也会破坏该数据结构,则还需要保持对该对象的实时引用。 垃圾收集器发现该方法不再使用ex变量,因此它可以,并且正如您所注意到的,在正确的情况下(即时间和需要)垃圾收集它。 正确的方法是在ex上调用gc.keepalive,因此将这一行代码添加到方法的底部,所有代码都应该是好的:
我通过阅读这本书了解到这种侵略行为 Applied .NET Framework Programming 作者:杰弗里·里克特。 |
![]() |
3
1
这看起来像工作线程和GC线程之间的竞争条件;为了避免这种情况,我认为有两种选择: (1)将if语句更改为使用ex.hash[0]而不是res,这样ex就不能过早地被gc使用,或者 (2)在调用哈希期间锁定ex 这是一个非常尖锐的例子——老师的观点是,JIT编译器中可能存在一个只在多核系统上显示的错误,还是这种编码在垃圾收集中可能有微妙的竞争条件? |
![]() |
4
1
我想你看到的是 合理的 由于在多个线程上运行而导致的行为。这就是gc.keepalive()方法的原因,在本例中应该使用该方法来告诉gc该对象仍在使用中,并且它不是清理的候选对象。 查看“完整代码”响应中的DoWork函数,问题是在这行代码之后:
函数不再引用 前任 对象,因此它可以在此时进行垃圾收集。添加对gc.keepalive的调用可以防止这种情况发生。 |
![]() |
5
1
是的,这是一个 issue 那有 come up before . 更有趣的是,你需要运行释放来实现这一点,你最终会绞尽脑汁“啊,怎么可能是空的?”. |
![]() |
6
1
来自ChrisBrumme博客的有趣评论http://blogs.msdn.com/cbrumme/archive/2003/04/19/51365.aspx
|
![]() |
7
1
这对于在Do-Work方法中调用终结器是完全正常的,就像在 例如散列调用,clr知道不再需要ex实例… 现在,如果要使实例保持活动状态,请执行以下操作:
gc.keepalive确实…什么都没有:)这是一个空的、不可内联的/jittable方法,其唯一目的是诱使GC认为在此之后将使用该对象。 警告:如果DoOrk方法是一个托管C++方法,您的示例是完全有效的…你 做 如果不希望从另一个线程中调用析构函数,则必须手动保持托管实例的活动状态。例如,传递对托管对象的引用,该对象在完成时将删除非托管内存的blob,而该方法使用的是相同的blob。如果不将实例保持活动状态,则在GC和方法线程之间会有一个争用条件。 最后会流下眼泪。管理堆损坏… |
![]() |
8
0
完整代码您将在完整代码下面找到,从VisualC++ 2008 .cs文件复制/粘贴。因为我现在在Linux上,没有任何单编译程序或它的使用知识,所以我现在无法进行测试。不过,几个小时前,我看到了这段代码的工作和它的bug:
对于那些感兴趣的人,我可以通过电子邮件发送压缩项目。 |
|
Robert King · Unity C#语法问题-转换位置 1 年前 |
![]() |
JBryanB · 如何从基本抽象类访问类属性 1 年前 |
|
law · 检查答案按钮的输入字符串格式不正确 2 年前 |
![]() |
i_sniff_ket · 在unity之外使用unity类 2 年前 |