製品の 1 つが本番環境で GB 単位のメモリを消費するという長期的な問題がありました。サーバーでメモリ不足の警告が表示されることがよくありますが、ついに今日、メモリプロファイラーと一緒に座って、メモリがどこに向かっているのかを確認する機会がありました. 開発中、同じデータベースと構成で、アプリケーションのプライベート ワーキング セットは 450MB です。本番サーバーでは、そのプロセスに割り当てられたメモリの量は 3.7GB です。
Ants Memory Profiler を使用して、そのメモリの 2.906GB がジェネレーション 1 ヒープに割り当てられていることを確認しました。
この量のメモリは、データベースから大量のデータをロードしていくつかのキャッシュを生成するため、アプリケーションの起動時に使用されます。ただし、上記のグラフのすべてのデータが割り当てられているが使用されていないという事実からわかるように、すべてがクリーンアップされます。完全な概要は次のとおりです。
ご覧のとおり、LOH はほとんど空で、断片化されていません。CompactOnce を適切な GCSettings 列挙型に具体的に設定しない限り、LOH が圧縮されないことはわかっています。しかし、ジェネレーション 0 から 2 のヒープは圧縮され、空き領域が解放されるはずだという印象を受けましたか? それとも、CLR は、その量のメモリが一度消費されたので、アプリケーションが再び同じ量のメモリを必要とする場合に備えて、そのメモリをアドレス指定し続ける必要があると想定していますか?
私にとって、私たちのアプリは約 600 ~ 700 MB しか消費しないはずです (そのほとんどは CLR です)。そう:
- この空き領域が割り当てられたままであり、開発用ラップトップではなく運用サーバーにのみ割り当てられている理由を知っている人はいますか?
- この空きメモリを gen 1 ヒープから手動で解放する方法はありますか?