まず例を見てみましょう
var_dump(memory_get_usage());
$a = "laruence";
var_dump(memory_get_usage());
unset($a);
var_dump(memory_get_usage()) ;
出力 (私のパソコンでは、システム、PHP バージョン、ロードされた拡張機能によって異なる場合があります):
int(90440)
int(90640)
int(90472
注 90472-90440=32 )さまざまな結論 PHP の unset は実際にはメモリを解放しないという人もいれば、PHP の unset は大きな変数 (多数の文字列、大きな配列) が解放された場合にのみ実際にメモリを解放するという人もいます。 PHP レベルでメモリについて説明します
それでは、これらの 32 バイトはどこに行ったのでしょうか?
この質問に答えるために、次の 2 つの側面から見てみましょう:
行きますか?
まず第一に、PHP は C 言語とは異なり、メモリ割り当て関連の API を明示的に呼び出した場合にのみメモリ割り当てが行われます
つまり、PHP では多くのメモリ割り当てが行われます。たとえば、次の場合:
$a = "laruence";
暗黙的なメモリ割り当てポイントは次のとおりです:
1. 変数名にメモリを割り当て、シンボル テーブルを格納します
2. にメモリを割り当てます。変数の値
したがって、見た目だけを見ることはできません
第二に、PHP の unset が実際にメモリを解放することを疑ってはいけません (もちろん、参照とカウントも組み合わせる必要があります。私の記事を参照してください)。この部分については前回の記事) この記事では PHP の原則 (変数の分離/参照) について詳しく説明していますが、このリリースは C プログラミングの意味でのリリースではなく、
PHP の場合は OS に戻されません。 、それ自体が C 言語のメモリ管理 API に似た一連のメモリ割り当てを提供します。これらの API は C API の意味に対応し、メモリはこれらの API を通じて PHP 内で管理されます。
emalloc を呼び出してメモリを適用すると、PHPたとえば、OS は大きなメモリ ブロックを必要とし、その一部を申請者に割り当てます。このように、メモリを適用するロジックがある場合でも、メモリを要求する必要はありません。頻繁なシステムコールを避けるために、OS からメモリを申請する必要があります。
たとえば次の例:
var_dump(memory_get_usage(TRUE)) // 取得されるのは real_size であることに注意してください
$a = "ラルエンス";
var_dump(memory_get_usage(TRUE));
unset($a);
出力:
int(262144)
int(262144) t(262144
)つまり、変数 $a を定義すると、PHP はシステムからの新しいメモリを適用しません
同じです。
このようにして、メモリを解放するために efree を呼び出すと、PHP はメモリを OS に返しませんが、このメモリを、小さなメモリの場合は保持している空きメモリ リストに追加します。
おそらく、それをメモリ キャッシュ リストに追加します (追記、私が確認した PHP5.2.4、5.2.6、5.2.8 などの PHP の一部のバージョンでは、
get_memory_usage() を呼び出すとき、メモリ キャッシュ リスト内の利用可能なメモリ ブロック サイズは減算されないため、設定解除後もメモリが変更されていないように見えます)。
それでは、これらの 32 バイトがどこに行くのか答えましょう。先ほど述べたように、多くのメモリ割り当てプロセスは明示的ではありません。次のコードを読むとわかります:
var_dump("I am www.7di.net");
var_dump(memory_get_usage());
$a = "ラルエンス";
var_dump(memory_get_usage());
unset($a);
var_dump(memory_get_usage());
出力:
string(43) "私は www .7di.net"
int(90808 ) //代入前
int(90976)
int(90808) //はい、メモリは正常に解放されます
90808-90808 = 0、通常、つまりこれらの 32 ワード このセクションは出力関数によって占有されます (厳密に言えば、出力ヘッダーによって占有されます)
増加するだけで減少しない配列
ハッシュテーブルは PHP の中核構造です (ハッシュテーブルを理解するには、私の以前の記事を参照してください) PHP 配列 (走査順序))、次のコードの場合、配列も彼女によって表され、シンボル テーブルも連想配列です:
var_dump("I am www.7di.net");
var_dump(memory_get_usage ( ));
$array = array_fill(1, 100, "laruence");
foreach ($array as $key => $value) {
${$value . $key} = NULL;
}
var_dump (memory_get_usage());
foreach ($array as $key=> $value) {
unset(${$value . $key});
}
var_dump(memory_get_usage());
100 個の変数を定義し、[Unset] を押して出力を確認しました:
string(43) "I am www.7di.net"
int(93560)
int(118848)
int(104448
すごい、なぜそこにあるのですかそれほどメモリが少ないのですか?
これは、Hashtable を定義するときに、未知の数の要素を保存するのに十分なメモリ ブロックを一度に割り当てることが不可能であるためです。そのため、PHP はメモリ ブロックのごく一部を HashTable に割り当てるだけです。 、容量が足りない場合は RESIZE して容量を拡張します
そして Hashtable、
容量を拡張することはできますが、容量を減らすことはできません。上記の例では、100 個の変数を保存したときに、シンボル テーブルでは不十分だったので、拡張を行いました。
これら 100 個の変数を順番に設定解除すると、変数によって占有されていたメモリは解放されます (118848 – 104448) が、シンボル テーブルは縮小されません。
つまり、少量のメモリがシンボル テーブル自体によって占有されることになります...
さて、PHP のメモリ管理についての予備的な理解はできましたか?