3

統合サービスとして使用されている Windows サービスでのメモリ リークのトラブルシューティングを行っています。

「doIntegration()」呼び出しごとに、メモリ使用量が呼び出し前よりも高くなり、呼び出しごとに約 0.5 MB 増加することがわかります。

PerfView を使用して、メモリ リークの可能性がある場所を特定しようとしました。

トラブルシューティング方法:

1) 最初の doIntegraion 呼び出しの前にヒープ スナップショットを取得する

2) doIntegration 呼び出しの後にヒープ スナップショットを取得する

3) ステップ 2 を複数回実行する

4)呼び出しごとにどのメソッド/グループが高くなるかを確認します

5) 個別のスナップショットの差分を使用して、メモリ リークが発生している場所を特定します。

LIB mscorlib!RuntypeTypeが毎回高くなるメソッド/グループであることがわかります。それを参照するものを確認しようとすると、

  • 固定ハンドル
    • .NET ルート

そして、ツリーをこれ以上拡張することはできません。

ビュー RefTree を選択すると、さらに多くのものが表示されます。

  • ルート 100%
    • .NET ルート 100%
      • ピンハンドル 70.6%
        • LIB mscorlib!RuntimeType 46%
        • LIB mscorlib!reflection.... 13.4% ...
      • 静的変数 30.7%
        • ns.ConfigurationSettings 5​​9.5%
        • ns.Leaks.ConfigurationSettings -33.3%

いくつかのスナップショットで diff を実行しましたが、インクリメントする唯一のメソッド/グループは Pinned ハンドルであり、それらは mscorlib タイプのみを参照しています。

他の誰かがこの種の問題を抱えていましたか?

問題は、XMLSerializer を使用した Model から XML へのシリアル化にあるのではないかと思いますが、よくわかりません。

メモリリークを見つけようとする別の方法を知っている人はいますか?

ありがとう :)

4

1 に答える 1

4

答えはかなり遅くなります。しかし、「doWork」ごとにメモリ使用量を増やしたのはシリアライザーであるという私の仮定は正しかった。

XmlSerializer には、初期化ごとに一時アセンブリを実際に作成するいくつかの「厄介な」コンストラクターがあり、それらは GC によって収集されません。

厄介なコンストラクターの 1 つを使用するさまざまな XmlSerializers をキャッシュして、一時アセンブリが 1 回だけ作成されるようにしました。

これで、メモリ リークはなくなりました。

于 2015-11-24T09:11:52.753 に答える