1

Aspen Plus というシミュレーション ソフトウェアへの COM インターフェイスにアクセスする C# プログラムがあります。非常に奇妙なメモリリークがあります。

シミュレーションから結果値を取得する必要がある場合は、このような一連の呼び出しを実行します。場合によっては、返される変数が null になる可能性があるため、そのためのチェックを挿入します。次に、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 リークします。最初は、ガベージ コレクターが最終的に実行されてクリーンアップされると思っていましたが、ダイスはありませんでした。数百回のシミュレーションを実行した後、メモリが不足しました。

奇妙なことに、以下のコードは正常に動作し、リークしません。null 参照をチェックするために 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