3

この質問は、以前に尋ねた質問の拡張です: Python デリゲート パターン - 循環参照を回避する方法は? 返信を読んだ後、質問を明確にすることにしましたが、個別に投稿するように求められました.

ここに行きます:

  1. Python ドキュメント (以下に転載) の一節では、ガベージ コレクションが循環参照オブジェクトに対して保証されていないと述べています。ここで見つけた投稿は、同じことを示唆しています。しかし、私の以前の質問への回答は同意しません。それで、私はその箇所を誤解しましたか、それとも見逃した詳細がありますか?
  2. 質問に対する Alex Martelli の回答で述べられているように、弱い参照を使用していると思います。彼の返信で言及されている循環参照オブジェクトのガベージコレクションのオーバーヘッドを完全に回避できますか? もしそうなら、それはどのように機能しますか?

関連する Python ドキュメントは、Python のドキュメントからの次の箇所の競合を示唆しています。

CPython 実装の詳細: CPython は現在、循環的にリンクされたガベージの (オプションの) 遅延検出を伴う参照カウント スキームを使用しています。循環ガーベッジの収集の制御については、gc モジュールの資料を参照してください。他の実装では動作が異なり、CPython は変更される可能性があります。オブジェクトが到達不能になったときにオブジェクトの即時ファイナライズに依存しないでください (例: 常にファイルを閉じます)。

元の形式のパッセージはここにあります: http://docs.python.org/reference/datamodel.html太字の設定は私のものです。

返信ありがとうございます。

4

2 に答える 2

2

循環参照を持つオブジェクトが収集されることが保証されない最も重要な理由は、設計上、Pythonがメソッドを定義している場合、循環参照を持つオブジェクトを収集しないことです。かなり簡単な理由があります: __del__

__del__()一般に、Pythonがメソッドを実行する安全な順序を推測することはできないため、Pythonはそのようなサイクルを自動的に収集しません。

これが、循環参照を持つ到達不能なオブジェクトが検出されない可能性がある唯一の理由であるとは言いたくありません。GCのサイクル検出メカニズムを失敗させる可能性のあるいくつかの異常な状況がおそらくあります。__del__ただし、オブジェクトの1つを定義しない限り、おそらく大丈夫です。心配する必要はありません。パフォーマンスの問題が発生した場合は、GCの広範なデバッグオプションを使用してください。

于 2012-05-17T03:20:12.150 に答える
1

循環参照を収集することが保証されていないと言うとき、それはまさにそれが意味することです。データ構造に循環参照が含まれている場合は常に、参照カウントは常にゼロ以外になります。つまり、参照カウントだけでは、それらを削除するタイミングを決定するのに十分ではありません。一方、各スコープの最後に到達した後ですべての循環参照を見つけるのは、控えめに言っても時間がかかります。ゼロ以外の参照カウントを持つすべてのオブジェクトの関係を分析する必要があります。

とは言っても、一般的には問題があるとは思いません。軽いスクリプトの場合は、無視してかまいません。他のものについては、たとえば C の場合のように、スコープの最後で何らかのクリーンアップ作業 (ファイルを閉じるか、循環参照を削除することさえ) を行う必要がありますが、それでも C ほど面倒ではありません。

問題が発生した場合は、各データ オブジェクトを終了する前に循環参照を削除してください。

于 2012-05-17T02:17:13.707 に答える