PHP の循環参照問題の規模はどれくらいですか? それについて心配する必要がありますか?

StackOverflow https://stackoverflow.com/questions/530179

質問

以下のコードのようなノードのツリー構造を使用している場合、循環参照について心配する必要がありますか?
PHP はメモリ割り当てメカニズムを使用しているため、循環参照が含まれる場合、ガベージ コレクターの動作が非常に困難になる可能性があると読みました。

私が知りたいのは:

  • ツリーが少数のノード (たとえば 25 個) だけで構成されている場合、これは問題ですか?
  • メモリはスクリプトの最後に解放されるのでしょうか、それともサーバーにゆっくりと問題を引き起こしているのでしょうか?
  • この問題はどのような状況でスクリプトの実行中に影響しますか?
  • 参照を手動で破棄すると問題は解決しますか? 常にそうする必要がありますか?
class Node {
    private $parent;
    private $children;

    function addChild( Node $child ) {
        $this->children[] = $child;
        $child->setParent( $this );
    }

    function setParent( $parent ) {
        $this->parent = $parent;
    }
}

//eg
$node0 = new Node;
$node1 = new Node;

// nodes 1 and 2 have a circular reference to each other
$node0->addChild( $node1 );
役に立ちましたか?

解決

ポイントごとに:

  • ツリーが少数のノード (たとえば 25 個) だけで構成されている場合、これは問題ですか?

ノードが本物のモンスターでない限り、そうではありません。

  • メモリはスクリプトの最後に解放されるのでしょうか、それともサーバーにゆっくりと問題を引き起こしているのでしょうか?

インタプリタがシャットダウンすると、すべてのメモリが解放されます。

  • この問題はどのような状況でスクリプトの実行中に影響しますか?

メモリ制限が非常に低い場合や、非常に大規模な動的データ構造がない限り、心配する必要はないと思います。頻繁に作成/解放されないノードが 25 個ある場合は、問題は発生しません。

  • 参照を手動で破棄すると問題は解決しますか? 常にそうする必要がありますか?

それが役立ちます。Propel を使用して大規模なデータセットをデータベースにロードするときに、解放されない循環参照を追跡するメモリ消費に関する多くの問題に遭遇しました。私たちの解決策は、すべての参照をクリアするメソッドを呼び出すことでした。

他のヒント

そうかもしれないが、それはすべての要求(あなたがキャッシュしている場合を除く)の最後にすべてのオブジェクトをスローするので、私は多くのPHPプログラマはこの心配はないと思う。

あなたがPHPでコマンドラインスクリプトを書いている場合は、多分あなたはそれを心配するためのケースを持っているが、それは心配を価値のあるものになる前に、あなたはかなり複雑なPHPコードを書くことにする必要があると思います。その場合は、あなたは大きな問題を抱えてます。

幸運ます。

ほとんどのPHPページの性質を考える - つまり、プロセスは、Webページのために実行され、完了時に捨てている - 私はむしろこれが問題である疑い。私は前に循環参照の問題を見ていないとの問題もなく、それらを使用しています。私の経験で、あなたは単なるメモリ消費量でより多くの問題に実行されますが、PHP 5は、特に断りがない限り、単にコピーしたオブジェクトや配列から離れてシフトすることにより、多少ことを軽減しています。

PHP 5.3は、循環参照検出および破壊の特徴を含むであろう。これはオプションの設定だし、ガベージコレクタは、パフォーマンスヒットがかかりますので、必要な場合にのみ使用されるべきですが、それのテーラーはあなたの例のために作られました。

今の開発、__destruct()メソッドで明示的に間接参照予防措置を取り、可能な場合は5.3にアップグレードしてください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top