今日は午前中ずっと、以前にメモリの問題を解決したコードを確認しましたが、一度に 40,000 個のデータをインポートするコードの最適化プログラムには非常に不満があります。これが根本的な解決策だと思います。オンライン検索を通じて、問題をさらに分析できます。
PHP のメモリ オーバーフローの問題では、最初の 2 つの方法については言及しません (エキスポの「About PHP Memory Release Issues」を参照してください)。問題の鍵が にあることを分析するのは難しくありません。ループ内で同期する方法。一度解放するために何百回もループするのではなく、メモリを解放します。ループ内の再利用性の高いコードを関数にカプセル化し、サブルーチンを呼び出す形式を使用するとデバッグ中にわかるからです。 -関数を使用すると、プログラムの実行速度が数十倍程度低下しますが、この低下はデータ量によって変化します。
ネストされたループの形式で、大量のデータを含む配列を処理する場合、多くの場合、時間内にメモリを解放するために unset($a) が使用されますが、実際には、そうすることは無意味です。
"エンジンでは、変数名とその値は実際には 2 つの異なる概念です。値自体は名前のない zval* ストレージ (この場合は文字列値) であり、zend_hash_add() を介して渡され、変数 $a 両方の変数名が同じ値を指している場合はどうなりますか?
{
zval *helloval;
MAKE_STD_ZVAL(helloval);
ZVAL_STRING(helloval, "Hello World", 1);
zend_hash_add(EG(active_symbol_table), "a", sizeof("a"), &helloval, sizeof(zval*), NULL);
zend_hash_add(EG(active_symbol_table), "b", sizeof("b"), &helloval, sizeof(zval*), NULL);
}
この時点で、$a または $b を実際に見ると、どちらにも文字列「Hello World」が含まれていることがわかります。残念ながら、次に、コードの 3 行目「unset($a);」の実行を続けます。現時点では、unset() は $a 変数が指すデータが別の変数でも使用されていることを知らないため、ただ盲目的にメモリを解放します。それ以降の変数 $b へのアクセスは、メモリ領域が解放されたものとして解釈されるため、エンジンがクラッシュします。
この問題は、zval の 4 番目のメンバー refcount (いくつかの形式があります) を利用して解決できます。変数が最初に作成されて値が割り当てられると、その refcount は 1 に初期化されます。これは、変数が最初に作成されたときに対応する変数によってのみ使用されると想定されるためです。コード スニペットが helloval を $b に割り当て始めると、refcount の値を 2 に増やす必要があるため、値は 2 つの変数によって参照されるようになります。
{
zval *helloval;
MAKE_STD_ZVAL(helloval);
ZVAL_STRING(helloval, "Hello World", 1);
zend_hash_add(EG(active_symbol_table), "a", sizeof("a"), &helloval, sizeof(zval*), NULL);
ZVAL_ADDREF(helloval);
zend_hash_add(EG(active_symbol_table), "b", sizeof("b"), &helloval, sizeof(zval*), NULL);
}
ここで、unset() が元の変数から $a の対応するコピーを削除すると、refcount パラメーターからデータに関心のあるユーザーが他にいることを確認できるため、refcount カウントをデクリメントするだけです。値を評価してから放っておいてください。 「
要約すると、実際に最も行う必要があるのは、データが最初に格納される配列を減らすことです。上記の例では、配列内の処理された要素がループ中に解放されるため、メモリ使用量が減少します。ループが続くにつれて増加し続けますが、常に増加するわけではなく、変動(メモリの再利用メカニズムの問題)が発生し、当初の目的は達成されます。もちろん、一度に処理されるデータの最大量は、サーバーによって PHP に割り当てられるメモリに依存します。一度に配列に読み込まれるデータ量がその制限を超えると、神でもできなくなります。何でも、ははは。