我正在开发一个Outlook Addin,我创建了很多COM对象(Outlook邮件,Outlook文件夹等).我的理解是,由于这些对象是COM对象,CLR不会从这些对象释放内存,我将不得不照顾从这些对象释放内存.所以我从这些对象释放内存
Marshal.ReleaseComObject的(对象);
但不幸的是,这似乎不起作用.然后我在Marshal.ReleaseComObject(Object)之后放了一个GC.Collect()语句;并且这个工作.之后我没有得到任何与内存相关的异常.我的问题是,如果CLR可以从COM对象中重新调用内存,为什么它不能单独执行.如果它不能,那么GC.Collect()语句如何在我的情况下工作.
您需要很好地理解Runtime Callable Wrapper才能将COM与.Net结合使用.基本上,您在.Net代码中作为COM对象引用的所有内容实际上都是对RCW的引用.RCW通过计算底层COM对象的引用数来管理它的引用计数,当它上的引用计数降为0时,它将Release在底层对象上调用(一次).当RCW处于活动状态时,它将在COM对象上维护单个引用.
该ReleaseComObjectAPI将通过1.减少对RCW的引用计数.如果这会带来对RCW的引用计数为0,那么RCW将调用ReleaseCOM对象,否则不是.还有FinalReleaseComObject一个会导致RCW上的引用计数变为0(从而导致RCW调用Release),但如果RCW上有其他未完成的引用,则它们可能会出错,这有点冒险.
"正常",当引用它的对象被垃圾收集时,RCW上的引用被管理 - 这可以解释为什么在强制垃圾收集时看到COM对象被释放的原因.这与我们对RCW如何工作的了解相结合告诉我们RCW上还有其他参考文献,你也需要"调用" ReleaseComObject以引导它Release.
调用ReleaseComObject是围绕.Net运行时的最终运行,您必须非常小心地管理所有创建的引用.创建的一些引用是"隐式"引用 - 这些引用的原因是调用返回引用的属性,然后调用它们.当你做这样的事情时,这有时被称为"太多点"问题:
object.foo.blah.baz.something()
Run Code Online (Sandbox Code Playgroud)
"foo","blah"和"baz"可能都是某些需要考虑的COM对象的引用.
| 归档时间: |
|
| 查看次数: |
865 次 |
| 最近记录: |