スレッド化された応答ハンドラーを生成するサーバー サブクラスがあり、ハンドラーはアプリケーション スレッドを開始します。ObjGraphを使用する場合を除いて、すべてが順調に進んでいます (実行中のアプリケーション スレッドの数が正しいことがわかります (私は負荷テストを行っており、35 個のアプリケーション インスタンスを実行し続けるように調整しています)。
objgraph.typestats()を呼び出すと、(GC に従って) 現在インタープリター内に存在する各オブジェクトのインスタンス数の内訳が提供されます。メモリ リークの出力を見ると、700 個のロガー インスタンスが見つかりました。これは、サーバーによって生成された応答ハンドラーの総数です。
アプリケーション スレッドが run() メソッドを終了するときに logger.removehandler(memoryhandler) と logger.removehandler(filehandler) を呼び出して、ロガー インスタンスへの参照が残っていないことを確認しました。また、ロガー インスタンスはアプリケーション スレッド内で完全に分離されています。 (それへの外部参照はありません)。これらのロガー インスタンスを排除する最後の手段として、run() の最後のステートメントは del self.logger です。
init() でロガーを取得するために、適切な大きさの乱数を指定して名前を付け、ファイル アクセスで区別できるようにします。ログ ファイル名の一部として同じ大きな数を使用して、アプリケーション ログの衝突を回避します。
要するに、GC によって追跡される 700 のロガー インスタンスがありますが、アクティブなスレッドは 35 しかありません。これらのロガーを強制終了するにはどうすればよいですか? より面倒なエンジニアのソリューションは、ロガーのプールを作成し、アプリケーション スレッドの存続期間中 1 つだけを取得することですが、GC が単純にこれを自動的に処理する必要がある場合に、維持するコードがさらに作成されます。