ホームページ  >  記事  >  バックエンド開発  >  PHP オブジェクトが相互参照する場合のメモリ オーバーフローの分析例、PHP サンプル分析_PHP チュートリアル

PHP オブジェクトが相互参照する場合のメモリ オーバーフローの分析例、PHP サンプル分析_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:19:56739ブラウズ

相互参照するPHPオブジェクトのメモリオーバーフローインスタンス分析、PHPインスタンス分析

一般的に言えば、スクリプト言語を使用する最大の利点の 1 つは、自動ガベージ コレクション メカニズムを使用してメモリを解放できることです。変数を使用した後にメモリを解放する処理は PHP が自動的に実行するため、何も行う必要はありません。
もちろん、必要に応じて unset() 関数を呼び出してメモリを解放することもできますが、通常はこれを行う必要はありません。
ただし、PHP では、unset() を手動で呼び出した場合でも、メモリが自動的に解放されない状況が少なくとも 1 つあります。詳細については、PHP 公式 Web サイト http://bugs.php.net/bug.php?id=33595 のメモリ リークの分析を参照してください。

問題の症状は次のとおりです:

「親オブジェクト-子オブジェクト」など、2 つのオブジェクト間に相互参照関係がある場合、親オブジェクトで unset() を呼び出しても、子オブジェクトで親オブジェクトを参照しているメモリは解放されません (親オブジェクトがガベージが収集されました。どちらも無理です)。

少し混乱していますか?次のコードを見てみましょう:

リーリー

このコードを実行すると、メモリ使用量が枯渇するまでどんどん増加することがわかります。

リーリー

ほとんどの PHP プログラマーにとって、この状況は問題ではありません。ただし、実行時間の長いコードで相互参照するオブジェクトを多数使用する場合、特にオブジェクトが比較的大きい場合は、メモリがすぐに使い果たされてしまいます。

ユーザーランドソリューション

少し面倒で洗練されていませんが、前述の bugs.php.net リンクに解決策が記載されています。
このソリューションでは、オブジェクトを解放する前にデストラクター メソッドを使用して、この目標を達成します。 Destructor メソッドはすべての内部親オブジェクト参照をクリアできます。これは、そうでなければオーバーフローするメモリのこの部分を解放できることを意味します。

「修正された」コードは次のとおりです:

リーリー

新しい Foo::__destruct() メソッドと、オブジェクトを解放する前の $foo->__destruct() の呼び出しに注意してください。このコードはメモリ使用量の増加の問題を解決し、コードが正常に動作できるようになりました。

PHP カーネル ソリューション

なぜメモリオーバーフローが発生するのですか?私は PHP カーネルの研究には詳しくありませんが、この問題は参照カウントに関連していると確信しています。
この時点では、親オブジェクト $foo が解放されるため、PHP は $foo オブジェクトがまだ必要であると判断し、メモリのこの部分を解放しません。原理はほぼ同じです。

平たく言えば、一般的な意味は次のとおりです。参照カウントはデクリメントされないため、一部のメモリは決して解放されません。
さらに、前述の bugs.php.net リンクでは、ガベージ コレクション プロセスを変更すると優れたパフォーマンスが犠牲になるため、読者はこれに注意する必要があると指摘しています。

ガベージ コレクション プロセスを変更する代わりに、unset() を使用して内部オブジェクトを解放してみてはいかがでしょうか? (またはオブジェクトを解放するときに __destruct() を呼び出しますか?)
おそらく、PHP カーネル開発者は、このガベージ コレクション メカニズムをここまたは他の場所で変更できるでしょう。

この記事で説明されている内容は、誰もが PHP の動作原理を深く理解するのに役立つと信じています。

PHP オブジェクトのマルチレベル参照を参照するにはどうすればよいですか?

class Fruit{
protected $con = array();

function aa(){
$this->con[0] = new Apple();
$this->con[1] = new Banana( );
echo $this->con[0]->sweet;
}
}

Android のメモリがオーバーフローしたときに、どのオブジェクト リソースが参照または占有されているかを確認するにはどうすればよいですか?

疑わしいオブジェクトの参照を弱い参照に変更してみてください。弱い参照はメモリ オーバーフローの問題を非常にうまく解決できます。

http://www.bkjia.com/PHPjc/871098.htmlwww.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/871098.html技術記事 PHP オブジェクトが相互に参照するメモリ オーバーフロー インスタンスの分析、PHP インスタンス分析 一般的に、スクリプト言語を使用する最大の利点の 1 つは、自動ガベージ コレクション メカニズムを使用してメモリを解放できることです...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。