検索
ホームページphp教程php手册PHPer はリソースを手動で解放してください

昨日までこれが問題だとは思いませんでした。

昨夜、私はこの機能を実装するための RFC を提出しました。その出発点は非常に簡単でした。なぜなら、私は議論を見ただけで、誰かがそれを理解していなかった、と言いました。それで気づきました。

それをメールグループに送った後、開発チームの同級生であるニキータ・ポポフ(nikic)がこのRFCに強い反対を表明しました。もちろん、私たちがオンラインで議論したとき、彼は最初の議論について多くのことを言いました。彼の意見を述べた:

"リクエストが完了すると、PHP はすべてのリソースを解放します。そのため、リソースを解放するために fclose または mysql_close を呼び出す必要はありません。PHP が代わりにそれを実行します。"

そして彼は、fclose は C 関数ファミリーを継承するためだけに存在すると考えており、決して fclose を呼び出すことはないと言いました。

驚いたし、同じことを思っている人がどれだけいるのか分からなかったので、この記事を書くことにしました

PHP5.2以前のPHPではリソース管理に参照カウントを使用していましたが、zvalの参照カウントが0の場合は解放されますが、この設計はWebスクリプトを開発する場合には問題ありません。 Web スクリプトの特性と目的は実行時間が短く、長時間実行されないためです。循環参照によるリソース リークはリクエストの最後に解放されます。部分的な救済措置(バックアップ)。

ただし、PHP を使用する人が増えるにつれて、多くの人が一部のバックグラウンド スクリプトで PHP を使用するようになりました。これらのスクリプトは、循環参照があると長時間実行され、未使用のリソースを時間内に解放できなくなるという特徴があります。 、その後、これ スクリプトは最終的にメモリが不足して終了します。

そこで、PHP5.3以降、ユーザーが解決できない問題を解決するためにGCを導入しました。

これは歴史です。ここで最初の問題に戻りましょう。PHP はリクエストが完了した後にすべてのリソースを解放するため、手動で解放する必要はありません。 >

例を見てみましょう:

Mysql 最大接続数 (mysql.max_connections)

$db = mysql_connect() ; $resut = mysql_query();
// 処理結果...
usleep(500);

//mysql_close($db); たとえば、これを呼び出していないとしましょう

// 他のロジック、コストが 5 秒であると仮定します
スリープ(5);

exit(0); //終了

上記の例では、Mysql との接続を 5 秒間維持します。このようなスクリプトは一般的なアプリケーションには関係ありませんが、リクエスト量が多いスクリプトの場合、致命的な問題が発生します。

たとえば、ビジーなアプリケーションは 1 秒あたり 1,000 件のユーザーからのリクエストを処理する必要があります。5 秒間で何件のリクエストを行うことができますか? MySQL には最大接続数 (mysql.max_connections) があり、この数が一般的です。 2000 を超えないでください。デフォルトはこれより低くなります: (mysql.max_connections),

このコードにより、アプリケーションは正常にサービスを提供できなくなります。また、Mysql の処理が完了した後に接続を閉じれば、この問題は発生しません。

実際には、より現実的な問題が発生しました。次の例を見てください:

$mmc = new Memcached(); $mysql = mysql_connect();

//処理 mysql_close($mysql);
$mmc->close();



これは実際の教訓です。コードは、ある日突然、Mysql に問題が発生し、Mysql への接続に時間がかかりすぎました。最後に、接続数が多すぎると Memcache が失敗しました。

したがって、接続コストが最も高いリソースを最初に初期化する必要があります。

システム最大ハンドル (/proc/sys/fs/file-max)

これは非常に簡単です。ハンドルを解放せずにオープンし続けると、プロセスの最大ハンドル数にも制限がかかる可能性があります (ulimit -n)。 > システムコールが高い (システムコールが高い)

リクエストの完了後に PHP がすべてのリソースとメモリを正しく解放する理由は、スクリプトで新しいメモリを使用するときに、PHP が OS から大きなメモリ (ZEND_MM_SEG_SIZE サイズ) を申請し、それを A に割り当てるためです。必要なものに適した小さなメモリ。

この小さなメモリを使用しない場合、PHP はそれを OS に返さず、後続の処理のために保持します

malloc(3) によってシステム コール (brk(2)) が発生することがわかっています (もちろん mmap の可能性もあります。中国語のおかげで、ここでは詳細は考慮しません)。システム コールは高価です。

したがって、リソースの使用を終了し、期限内に解放しなかった場合、後続のロジックがメモリを要求すると、PHP は以前に要求した大きなメモリ ブロックが分割されたことを認識し、リソースへの malloc 呼び出しを行う必要があります。新しい大容量メモリを取得するには、OS が再度必要になります。また、この大容量メモリのマーキングも必要になります。

そして、リソースの使用を終了して時間内に解放すると、次回スクリプトがメモリを適用するときに、以前に返されたメモリ ブロックが再利用できるようになり、スクリプト全体が OS で一度だけメモリを適用するだけで済む可能性があります。 >

メモリのピーク使用量

これは上記と一定の関係があります。リソースの使用が終了すると、リソースは解放され、その後そのリソースを使用すると、PHP のメモリ使用量は次のようになります。

リソース+1 -> リソース-1 -> リソース-1 (ピーク値は 1)

そして、PHP リクエストが完了するまで待ってからリリースする場合:

リソース + 1 -> リソース + 1 …. -> リソース -1 (ピーク値は 2)

言い換えれば、よく書かれたスクリプトは、下手に書かれたスクリプトよりもピーク時のメモリを大幅に節約できる可能性があります。

たとえば、非常にビジーなサーバーの場合、10 個の PHP プロセスがあり、各 PHP プロセスの最大メモリは 1G で、サーバーには 8G しかメモリがありません。

結論

結論は明らかです。最初に述べたように、私はこれが問題だとは思っていませんでした。

ここで一言言わせてください。PHP の本を購入して、「PHP が自動的にリソースを解放してくれるため、PHP でリソースを積極的に解放する必要はありません」と書かれている場合は、それを焼くことをお勧めします。



声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール