1

我有一个 C# 程序,它可以访问一个名为 Aspen Plus 的模拟软件的 COM 接口。我有一个非常奇怪的内存泄漏。

当我需要从模拟中获取结果值时,我会运行一系列这样的调用,在某些情况下,返回的变量可能为空,所以我插入了一个检查。然后我使用 FinalReleaseComObject 清理 COM 引用。

   public override ValueType recvValueFromSim<ValueType>(string path) {
       Happ.IHNode tree = this.Aspen.Tree;
       dynamic node = tree.FindNode(path);
       ValueType retVal = default(ValueType);
       if (node != null && node.Value != null) {
           retVal = node.Value;
       }
       Marshal.FinalReleaseComObject(node);
       Marshal.FinalReleaseComObject(tree);
       node = null;
       return retVal;
   }

不幸的是,上面的代码泄漏了很多。每次模拟泄漏 2MB。起初我以为垃圾收集器最终会运行并清理它,但没有骰子。在运行了几百次模拟后,我的内存不足。

奇怪的是,下面的代码可以正常工作并且不会泄漏。我不喜欢它,因为使用 catch 检查空引用似乎是一种不好的形式,但这不会泄漏。

   public override ValueType recvValueFromSim<ValueType>(string path) {
      ValueType node;
      try {
         node = this.Aspen.Tree.FindNode(path).Value;
         return node;
      } catch {
         return default(ValueType);
      }
   }

为什么不漏?有人知道吗?这就是为什么我认为我知道临时引用和释放 COM 对象的原因。

4

0 回答 0