PHP 原則のメモリ管理におけるいくつかの難しい点
PHP のメモリ管理は 2 つの部分に分かれています。最初の部分は、参照カウント、コピーオンライト、およびその他のアプリケーション指向の管理です。今日紹介する zend_alloc は、利用可能なメモリの管理方法やメモリの割り当て方法など、PHP 独自のメモリ管理について説明します。
さらに、なぜこれを書くのかというと、PHP のメモリ管理で使用される戦略、データ構造、アルゴリズムを紹介する前に情報がないからです。しかし、私たちが通常拡張機能を開発したり PHP のバグを修正したりする場合、この部分についてはまったく知識がありません。十分な理解が必要です。PHP 開発チームの多くの友人はこれについてあまり理解していません。そのため、これについて具体的に書く必要があると思います。
基本的な概念については、コードを見れば簡単に理解できるので、詳細は説明しません。 ここでは、コードを見るとわかりにくい点を中心に紹介します。 ? はは、記事を書く前に、作業の重複を避けるために既存の情報を検索しましたが、TIPI プロジェクトのこの部分の説明を見たので、この部分は理解しにくいと思います。コードを見ても
現在、英語版の紹介文も作成中です: Zend MM
Zend Memory Manager (以下、Zend MM と呼びます) は、PHP のメモリ管理ロジックです: zend_mm_heap:
という重要なデータ構造があります。
Zend MM はメモリを小さいメモリと大きいメモリの 2 つのタイプに分け、それぞれを別々に扱います。小さいメモリの場合はこの部分が最もよく使用されるため、高いパフォーマンスを追求し、大きいメモリの場合は安定性を追求します。メモリの無駄です。
したがって、メモリが少ない場合、PHP ではキャッシュ メカニズムも導入しています。
Zend MM は、割り当てが 1 つの場所で見つかるように、可能な限りキャッシュを通じてこれを実現したいと考えています。
理解しにくい点の 1 つは、free_buckets のステートメントです:
Q: free_buckets 配列の長さが ZEND_MM_NUMBER_BUCKET なのはなぜですか?
A: これは、上の図の赤いボックスに示されているように、PHP が固定長配列を使用して ZEND_MM_NUMBER_BUCKET を格納するトリックを使用しているためです。使用されていない free_buckets 要素の唯一の有用なデータ構造は、next_free_block です。したがって、メモリを節約するために、PHP は ZEND_MM_NUMBER_BUCKET * sizeof(zend_mm_free_block) サイズのメモリを割り当てず、ZEND_MM_NUMBER_BUCKET * (sizeof(*next_free_block) + sizeof(*prev_free_block)) サイズのメモリのみを使用します。
ZEND_MM_SMALL_FREE_BUCKET マクロの定義を見てみましょう:
#define ZEND_MM_SMALL_FREE_BUCKET(ヒープ, インデックス)
(zend_mm_free_block*) ((char*)&heap->free_buckets[index * 2] +
sizeof(zend_mm_free_block*) * 2 -
sizeof(zend_mm_small_free_block))
その後、Zend MM は prev ポインターと next ポインターのみが使用されることを保証するため、メモリ読み取りエラーは発生しません。
次に、理解しにくい 2 番目の点は、PHP によるlarge_free_buckets の管理です。まず、割り当てについて説明します (この部分に関する TIPI プロジェクト チームの説明はやや曖昧です)。
静的 zend_mm_free_block *zend_mm_search_large_block(zend_mm_heap *ヒープ, size_t true_size)
large_free_buckets は、ツリーと双方向リストの組み合わせであると言えます:
large_free_buckets はマクロを使用して、特定のサイズのメモリがどのインデックスに該当するかを決定します:
#define ZEND_MM_LARGE_BUCKET_INDEX(S) zend_mm_high_bit(S)
zend_mm_high_bit は true_size の最上位ビット 1 のシリアル番号 (zend_mm_high_bit) を取得し、対応するアセンブリ命令は bsr です (ここで、TIPI プロジェクトのエラーの説明は次のとおりです)。「このハッシュ関数は、サイズの桁数を計算するために使用されます。戻り値はサイズ 1 ~ 1 の数値のバイナリ コードです。
言い換えれば、large_free_buckets の各要素は、対応するインデックスでサイズ 1 のメモリ ブロックへのポインターを保持します。これは少し複雑です。たとえば、次のようになります。
たとえば、large_free_buckets[2] は、サイズ 0b1000 ~ 0b1111 のメモリのみを保存します。別の例:large_free_buckets[6] は、サイズ 0b10000000 ~ 0b11111111 のメモリのポインタを保存します。このようにして、メモリを再割り当てするときに、Zend MM は検索に最適な領域をすばやく見つけることができ、パフォーマンスが向上します。
ただし、各要素は同じサイズのメモリ ブロックを維持する双方向リストでもあり、左右の子 (child[0] と child[1]) はそれぞれキー値 0 と 1 を表します。このキー値は ?
を参照していますか?たとえば、true_size が 0b11010 のメモリを PHP に適用したところ、PHP は、large_free_buckets で適切なメモリを見つけるために zend_mm_search_large_block のロジックを入力しました。
1. まず、true_size に対応するインデックスを計算します。計算方法は ZEND_MM_LARGE_BUCKET_INDEXで説明した通りです。
2. 次に、ビットマップ構造で、large_free_buckets にすでに存在する true_size より大きい使用可能なメモリがあるかどうかを確認します。存在しない場合は、次を返します。
size_t ビットマップ = ヒープ->large_free_bitmap >> インデックス;
if (ビットマップ == 0) {
NULL を返す;
}
3. free_buckets[index] に使用可能なメモリがあるかどうかを確認します:
if (UNEXPECTED((ビットマップ & 1) != 0))
4. 存在する場合は、free_buckets[index] から開始して、最適なメモリを見つけます。手順は次のとおりです。
4.1. free_buckets[index] から開始し、free_buckets[index] の現在のメモリ サイズが true_size に等しい場合、検索は終了し、正常に戻ります。
4.2. インデックスに対応する true_size の現在の最上位ビットを確認します (true_size << (ZEND_MM_NUM_BUCKETS - Index))。free_buckets[index]->child[1] の場合は検索を続けます。 ->child[1] が存在しない場合、true_size の現在の最上位ビットが 0 の場合は、free_buckets[index]->child[0] の下で検索を続けます。 0] ] が存在しない場合は、free_buckets[index]->child[1] の下で最小メモリを検索します (この時点では、free_buckets[index]->child[1] の下のメモリが存在することが保証されているため) true_size より大きい)4.3. 開始点を2の子に変更し、ture_sizeを1つ左に移動します。
5. 上記のロジックで適切なメモリが見つからない場合は、最小の「大きなメモリ ブロック」を検索します:
/* 最小の「大きい」空きブロックを検索 */
best_fit = p = heap->large_free_buckets[index + zend_mm_low_bit(bitmap)];
while ((p = p->child[p->child[0] != NULL])) {
if (ZEND_MM_FREE_BLOCK_SIZE(p) < ZEND_MM_FREE_BLOCK_SIZE(best_fit)) {
best_fit = p;
}
}
上記のロジック (p = p->child[p->child[0] != NULL]) に注意してください。PHP は最小のメモリを見つけようとしています。
large_free_buckets がキー ツリーであると言われるのはなぜですか? 上記のロジックから、PHP はバイナリ 01 に従ってサイズをキー化し、メモリ サイズ情報をキー ツリーに反映することで、迅速な検索を容易にすることがわかります。
さらに、rest_buckets は双方向リストであり、PHP の割り当て後に残りのメモリを保存し、残りのメモリを free_buckets に無意味に挿入することによって引き起こされるパフォーマンスの問題を回避するために使用されます (ここでは、TIPI プロジェクトのエラーの説明は次のとおりです)。 "これは要素が 2 つだけある配列です。一般的に使用される挿入操作と検索操作は最初の要素、つまり heap->rest_buckets[0] に対するものです。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









DALL-E 3は、前モデルより大幅に改良されたモデルとして2023年9月に正式導入されました。これは、複雑な詳細を含む画像を作成できる、これまでで最高の AI 画像ジェネレーターの 1 つと考えられています。ただし、発売当初は対象外でした

Index.html は Web ページのホームページ ファイルを表し、Web サイトのデフォルト ページです。ユーザーが Web サイトにアクセスすると、通常、index.html ページが最初に読み込まれます。 HTML (HypertextMarkupLanguage) は Web ページの作成に使用されるマークアップ言語であり、index.html も HTML ファイルです。これには、Web ページの構造とコンテンツに加えて、書式設定とレイアウトに使用されるタグと要素が含まれます。以下は、index.html コードの例です: <

ファイルのサイズを取得するには、Java の File.length() 関数を使用します。ファイル操作を扱うとき、ファイル サイズは非常に一般的な要件です。Java では、ファイルのサイズを取得するための非常に便利な方法、つまり length( ) File クラスのメソッド。この記事では、このメソッドを使用してファイルのサイズを取得する方法と、対応するコード例を紹介します。まず、サイズを取得したいファイルを表す File オブジェクトを作成する必要があります。 File オブジェクトを作成する方法は次のとおりです: Filef

PHP 実装フレームワーク: ZendFramework 入門チュートリアル ZendFramework は、PHP によって開発されたオープン ソースの Web サイト フレームワークであり、現在 ZendTechnologies によって保守されています。ZendFramework は、MVC デザイン パターンを採用し、Web2.0 アプリケーションと Web サーブの実装に役立つ一連の再利用可能なコード ライブラリを提供します。 。 ZendFramework は PHP 開発者に非常に人気があり、尊敬されており、幅広い機能を備えています。

Zend Framework でのアクセス許可制御に ACL (AccessControlList) を使用する方法 はじめに: Web アプリケーションでは、アクセス許可制御は重要な機能です。これにより、ユーザーはアクセスを許可されたページと機能にのみアクセスできるようになり、不正アクセスが防止されます。 Zend フレームワークは、ACL (AccessControlList) コンポーネントを使用してアクセス許可制御を実装する便利な方法を提供します。この記事では、Zend Framework で ACL を使用する方法を紹介します。

Linux システムでは、free コマンドは、システム メモリの使用状況を監視するために使用される重要なシステム ツールです。総メモリ、使用量、使用可能量などの情報を表示するための基本的な使用方法を示します。さらに、詳細なメモリ情報の表示、単位変換、メモリのリアルタイム監視などの高度な使用法もあります。 free コマンドの基本的な使用法: free コマンドの基本構文は次のとおりです: free [オプション] よく使用されるオプションをいくつか示します: -h: メモリ サイズを人間が判読できる方法で表示します。 -b: メモリサイズをバイト単位で表示します。 -k: メモリ サイズをキロバイト単位で表示します。 -m: メモリ サイズをメガバイト単位で表示します。 -g: メモリ サイズをギガバイト単位で表示します。サンプルコード: サンプルコードを見てみましょう

AI 対応の Deepin Linux ディストリビューションは、V23 RC2 と呼ばれる最新のアップデートを受け取りました。 Deepin のこのバージョンには、多数のパッケージ更新と新機能が付属しています。しかし、機能だけがすべてではありません。外観と感触が主なスポットライトです

タイトル: TreeSet クラスの size() メソッドを使用して、ツリー コレクション内の要素の数を取得します。はじめに TreeSet は、Java コレクション フレームワークの順序付きコレクションです。SortedSet インターフェイスを実装し、赤黒ツリー データ構造を使用して、それを実装します。 TreeSet は、要素の自然な順序に従って、または Comparator カスタム コンパレータを使用して並べ替えることができます。この記事では、TreeSet クラスの size() メソッドを使用して、ツリー コレクション内の要素の数を取得し、提供する方法を紹介します。
