【发布时间】:2011-01-20 04:55:49
【问题描述】:
C# 编译器或 JITter 完成的优化是否有明显的副作用?
我已经举过一个例子。
var x = new Something();
A(x);
B(x);
当调用A(x) 时,x 保证会一直保持到A 的末尾——因为B 使用相同的参数。但是如果B被定义为
public void B(Something x) { }
然后B(x) 可以被优化器消除,然后可能需要调用GC.KeepAlive(x)。
这种优化实际上可以由 JITter 完成吗?
除了堆栈跟踪更改之外,是否还有其他可能具有可见副作用的优化?
【问题讨论】:
-
如果
x不再被使用,为什么还要让它保持活跃? -
关于 JIT 优化的好文章请查看 codeproject.com/KB/dotnet/JITOptimizations.aspx - JITer 可能会优化掉空的方法调用,但会保留方法本身
-
@JSBangs:您可能希望让某些东西保持活动状态的原因是因为它的破坏会触发非托管代码在不希望的地方运行。例如,有些 COM 存储对象需要在包含它们的“外部”存储之前关闭“内部”存储(想想嵌套目录)。垃圾收集器可以确定不再使用代表外部存储的托管对象,并决定在清理仍然活动的内部存储之前清理它。在实践中,我不得不编写代码来处理这种情况,这真的很痛苦。
-
@Eric,但这不是
IDisposable的用途吗?外部存储持有对内部存储的引用,并在释放自己的资源之前对它们调用Dispose。希望您永远不必关心垃圾收集器何时声明某些内容。除非有问题的类是第 3 方库,否则您无法修改并且设计不佳,在这种情况下....... -
我指的是与 Eric 提到的非托管代码有关的案例。我不知道具体细节,因为我只是从 Eric 那里听说过它们,但这就是我在示例中所考虑的。
标签: c# optimization jit