ホームページ  >  記事  >  バックエンド開発  >  PHP ソース コードの簡単な説明 32: PHP メモリ プールの emalloc/efree 層とヒープ層

PHP ソース コードの簡単な説明 32: PHP メモリ プールの emalloc/efree 層とヒープ層

不言
不言オリジナル
2018-06-29 09:54:521995ブラウズ

この記事では主に PHP ソース コード 32: PHP メモリ プールの emalloc/efree 層とヒープ層について紹介します。必要な方は参考にしてください。 # PHP ソースコードに関する簡単な説明 32: PHP メモリ プールの emalloc/efree 層とヒープ層

emalloc/efree 層はメモリ システム全体の最上位構造であり、PHP 独自のメモリを使用してヒープ層交換を通過します。管理メカニズム。 USE_ZEND_ALLOC を 0 に設定すると、malloc/free などの関数を使用してメモリを直接操作できます。

ここでは、emalloc/efree 層とヒープ層の間の相互作用と、emalloc および efree 関数の実装からヒープ層のメモリ管理メカニズムを分析します。

[emalloc]

emalloc 関数は、zend_alloc.h の 70 行目から始まります。

emalloc は、_emalloc 関数に対応するマクロです。
_emalloc 関数では、zend のメモリ管理メカニズムが使用されていない場合は malloc 関数が直接呼び出され、そうでない場合は

_zend_mm_alloc_int
[emalloc() -> _emalloc() -> _zend_mm_alloc_int() ]
関数が呼び出されます。
_zend_mm_alloc_int 関数では、プログラムは実際に必要なメモリが十分であるかどうかを処理します。以下 ZEND_MM_MAX_SMALL_SIZE (272) の 2 つのケースで、ZEND_MM_MAX_SMALL_SIZE 未満の場合、free_buckets で適切なメモリ ブロックがあるかどうかを確認します。free_buckets で適切なブロックが見つかった場合は、ジャンプします。 zend_mm_finished_searching_for_block に直接、そうでない場合は zend_mm_search_large_block()


[emalloc() -> _zend_mm_alloc_int() -> zend_mm_search_large_block()]

zend_mm_search_large_block 関数が使用されます。 large_free_buckets のメモリ ブロック。 ZEND_MM_LARGE_BUCKET_INDEX (true_size) サイズが見つからない場合は、大きいブロック リストで最小のブロックを見つける必要があります。


大ブロックリストと小ブロックリストの両方に見つからない場合は、残りのリストブロックから検索する必要があります。見つかった場合は、zend_mm_finished_searching_for_blockにもジャンプします。 3 つのリストに見つからない場合は、メモリ割り当てを再度増やす必要があります。このとき、割り当てられるメモリのサイズが block_size よりも大きい場合は、ストレージ層の割り当て関数が呼び出されます。そうでない場合は、block_size のサイズのメモリが割り当てられます。直接割り当てられます。

メモリを割り当てた後、ヒープを再配置する必要があります。このとき、ヒープ内のメモリ サイズを再計算し、新しく割り当てられたメモリをsegments_listの先頭に追加する必要があります。


上記の操作で zend_mm_finished_searching_for_block に直接ジャンプする場合は、使用済みメモリ ブロックを対応するリストから削除する必要があります (これはマーキング プロセス、擬似削除である必要があります)

次に、状況に応じて、メモリがどのくらい残っているかを確認し、空きリストまたは残りのリストに移動します。

最後に割り当てられたブロックを返します。

emalloc のプロセス全体では、次の点に注意する必要があります。

ZEND_MM_BUCKET_INDEX(true_size) はバケット内の位置にあり、この値は 0 以上 32 未満です。

実装は次のとおりです。


#define ZEND_MM_BUCKET_INDEX(true_size) ((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2))

free_bitmap とlarge_free_bitmap の値は両方とも 0 ~ 31 です。

[efree]
efree 関数は、zend_alloc.h の 72 行目から始まります。

efree は、_efree 関数に対応するマクロです。

_efree 関数では、zend のメモリ管理メカニズムが使用されていない場合は、free 関数が直接呼び出されます。そうでない場合は、次のブロックの場合、__

zend_mm_free_int
[efree() -> _efree() -> _zend_mm_free_int() ]

Heap が最初にヒープ全体のサイズを削減します。現在のブロックの前のブロックがフリーブロックである場合、フリーブロックリストから次のフリーブロックを削除し、現在のブロックとマージします。 現在のブロックの前のブロックがフリーブロックである場合、前のフリーブロックをフリーブロックから削除します。リストを作成し、それを現在のブロックとマージすると、ポインターは前の空きブロックを指します。現在のブロックが開始ブロックである場合は、zend_mm_del_segment を呼び出してメモリ セグメント全体をクリアします。開始ブロックではない場合は、マージされたブロックが空きブロック リストに追加されます。

上記がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。

関連する推奨事項:

PHP ソース コードの簡単な説明 31: PHP メモリ プールのヒープ層の基本


PHP ソース コード 30 の簡単な説明: PHP メモリ プール内のストレージ層


PHP ソース コード 29 の簡単な説明: インターフェイスの継承について

以上がPHP ソース コードの簡単な説明 32: PHP メモリ プールの emalloc/efree 層とヒープ層の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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