c# - 如何使 JIT 将堆栈变量扩展到范围末尾(GC 太快)

标签 c# .net garbage-collection jit

我们正在处理 .Net 程序中 GC 太快的问题。 因为我们使用的是带有原生资源的类,并且没有调用GC.KeepAlive(),所以GC会在Native访问结束之前收集对象。结果程序崩溃了。 我们遇到的问题正是如下所述:

Does the .NET garbage collector perform predictive analysis of code?

像这样:

{  var img = new ImageWithNativePtr();
   IntPtr p = img.GetData();
   // DANGER!
   ProcessData(p);
}

要点是:JIT 生成的信息向 GC 显示在 GetData() 运行时未使用 img。如果 GC 线程在正确的时间出现,它会收集 img,然后程序就会崩溃。可以通过附加 GC.KeepAlive(img); 来解决这个问题 不幸的是,已经编写了太多代码(在太多地方)来轻松纠正问题。

因此:是否有一个属性(即 ImageWithNativePtr)可以使 JIT 的行为类似于调试版本?在调试版本中,变量 img 将保持有效,直到作用域结束 ( } ),而在发布版本中,它会在注释 DANGER 处失去有效性。

最佳答案

据我所知,没有办法根据方法引用的类型来控制抖动的行为。您也许可以归因于该方法本身,但这不会满足您的订单。既然如此,你就应该硬着头皮重写代码。 GC.KeepAlive 是一种选择。另一种方法是让 GetData 返回一个安全句柄,其中包含对该对象的引用,并让 ProcessData 接受该句柄而不是 IntPtr — 这就是无论如何,这是一个很好的做法。然后,GC 将保留安全句柄,直到方法返回。如果您的大部分代码都使用 var 而不是代码片段中的 IntPtr,您甚至可能无需修改每个方法即可逃脱。

关于c# - 如何使 JIT 将堆栈变量扩展到范围末尾(GC 太快),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6898336/

相关文章:

c# - 用于创建动态Where子句的表达式树抛出与参数相关的错误

c# - 您最喜欢的 C# 扩展方法是什么? (codeplex.com/extensionoverflow)

c# - JetBrains Rider 以 4.5 框架为目标,没有切换到 4.7 的选项

c# - Scintilla .NET 编辑器。将光标定位在第一条可见行

c# - .NET 垃圾收集器能否收集作为类成员的对象?

c# - 如何在 C# 中的此 SQL 语句中构建参数化查询或用户转义?

c# - 通用类型 T 作为变量名

c# - 在 C# 中按行和按分隔符读取带分隔符的文本文件

java - Java是如何解决垃圾回收中的retain cycles的?

python - Python 的垃圾收集器会损害我的应用程序吗?