PHP のメモリ管理は 2 つの部分に分かれています。最初の部分は、参照カウント、コピーオンライト、その他のアプリケーション指向の管理です。紹介したいのは、使用可能なメモリの管理方法、メモリの割り当て方法など、zend_alloc で記述されている PHP 自体のメモリ管理です
なお、戦略以前に PHP のメモリ管理に関する情報が存在しないため、なぜこれを書く必要があるのかについて説明します。通常、拡張機能を開発したり PHP のバグを修正したりする場合、PHP 開発チームの多くの友人はこの部分についてよく理解していません。なので、具体的に書く必要があると思います
基本的な概念については、コードを見ればわかりやすいので、詳しくは説明しません。 ここでは、簡単ではない点を中心に紹介します。コードを見れば理解できるのに、なぜそんなことを言うのですか?笑、記事を書く前に、作業の重複を避けるために既存の情報を検索したところ、TIPI プロジェクトのこの部分の説明がたくさんあることがわかりました。なので、この部分はコードを見ても分かりにくいと思います
現在、英語版の紹介文も作成中です: Zend MM
Zend Memory Manager、以下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 zend_mm_free_block を使用するトリックを使用しているためです。これは使用されないため、有用なデータ構造は next_free_block と prev_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 マクロの定義を見てみましょう:
<ol class="dp-xml"> <li class="alt"><span><span>#define ZEND_MM_SMALL_FREE_BUCKET(heap, index) </span></span></li> <li> <span> (zend_mm_free_block*) ((char*)&heap-</span><span class="tag">></span><span>free_buckets[index * 2] + </span> </li> <li class="alt"><span> sizeof(zend_mm_free_block*) * 2 - </span></li> <li><span> sizeof(zend_mm_small_free_block)) </span></li> </ol>
その後、Zend MM は prev と next ポインターのみが使用されることを保証するため、メモリ読み取りエラーは発生しません
。次に、理解しにくい 2 番目の点は、PHP によるlarge_free_buckets の管理です。まず割り当てを紹介します (この部分の TIPI プロジェクト チームの説明は少し曖昧で不明瞭です):
<ol class="dp-xml"><li class="alt"><span><span>static zend_mm_free_block *zend_mm_search_large_block(zend_mm_heap *heap, size_t true_size) </span></span></li></ol>
large_free_buckets は組み合わせであると言えます。ツリー構築と双方向リスト:

large_free_buckets は、メモリのインデックスを決定するマクロを使用します。特定のサイズが該当します:
<ol class="dp-c"><li class="alt"><span><span>#define ZEND_MM_LARGE_BUCKET_INDEX(S) zend_mm_high_bit(S) </span></span></li></ol>
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 は検索に最適な領域を素早く見つけることができます。
そして、各要素も 2 です。 -way リストは同じサイズのメモリ ブロックを維持し、左右の子 (child[0] と child[1]) はそれぞれキー値 0 と 1 を表します。このキー値は何を参照しますか?
例として、true_size が 0b11010 のメモリを PHP に適用しました。いくつかの手順を実行した後、PHP は、適切なメモリを見つけるために zend_mm_search_large_block を実行しました。 , true_sizeに対応するインデックスを計算します。計算方法は前に説明したとおりです。 ZEND_MM_LARGE_BUCKET_INDEX
2. 然后在一个位图结构中, 判断是否存在一个大于true_size的可用内存已经存在于large_free_buckets, 如果不存在就返回:
<ol class="dp-c"> <li class="alt"><span><span>size_t bitmap = heap->large_free_bitmap >> index; </span></span></li> <li> <span class="keyword">if</span><span> (bitmap == 0) { </span> </li> <li class="alt"> <span> </span><span class="keyword">return</span><span> NULL; </span> </li> <li><span>} </span></li> </ol>
3. 判断, free_buckets[index]是否存在可用的内存:
<ol class="dp-c"><li class="alt"><span><span class="keyword">if</span><span> (UNEXPECTED((bitmap & 1) != 0)) </span></span></li></ol>
4. 如果存在, 则从free_buckets[index]开始, 寻找最合适的内存, 步骤如下:
4.1. 从free_buckets[index]开始, 如果free_buckets[index]当前的内存大小和true_size相等, 则寻找结束, 成功返回.
4.2. 查看true_size对应index后(true_size child[1]下面继续寻找, 如果free_buckets[index]->child[1]不存在, 则跳出. 如果true_size的当前最高位为0, 则在free_buckets[index]->child[0]下面继续寻找, 如果free_buckets[index]->child[0]不存在, 则在free_buckets[index]->child[1]下面寻找最小内存(因为此时可以保证, 在free_buckets[index]->child[1]下面的内存都是大于true_size的)
4.3. 出发点变更为2中所述的child, 左移一位ture_size.
5. 如果上述逻辑并没有找到合适的内存, 则寻找最小的”大块内存”:
<ol class="dp-c"> <li class="alt"><span><span class="comment">/* Search for smallest "large" free block */</span><span> </span></span></li> <li><span> best_fit = p = heap->large_free_buckets[index + zend_mm_low_bit(bitmap)]; </span></li> <li class="alt"> <span> </span><span class="keyword">while</span><span> ((p = p->child[p->child[0] != NULL])) { </span> </li> <li> <span> </span><span class="keyword">if</span><span> (ZEND_MM_FREE_BLOCK_SIZE(p) </span> </li> <li class="alt"><span> best_fit = p; </span></li> <li><span> } </span></li> <li class="alt"><span> } </span></li> </ol>
注意上面的逻辑, (p = p->child[p->child[0] != NULL]), PHP在尽量寻找最小的内存.
为什么说, large_free_buckets是个键树呢, 从上面的逻辑我们可以看出, PHP把一个size, 按照二进制的0,1做键, 把内存大小信息反应到了键树上, 方便了快速查找.
另外, 还有一个rest_buckets, 这个结构是个双向列表, 用来保存一些PHP分配后剩下的内存, 避免无意义的把剩余内存插入free_buckets带来的性能问题(此处, TIPI项目错误的描述为: “这是一个只有两个元素的数组。 而我们常用的插入和查找操作是针对第一个元素,即heap->rest_buckets[0]“).
作者: Laruence( ) 原文地址:

データベースストレージセッションを使用することの主な利点には、持続性、スケーラビリティ、セキュリティが含まれます。 1。永続性:サーバーが再起動しても、セッションデータは変更されないままになります。 2。スケーラビリティ:分散システムに適用され、セッションデータが複数のサーバー間で同期されるようにします。 3。セキュリティ:データベースは、機密情報を保護するための暗号化されたストレージを提供します。

PHPでのカスタムセッション処理の実装は、SessionHandlerInterfaceインターフェイスを実装することで実行できます。具体的な手順には、次のものが含まれます。1)CussentsessionHandlerなどのSessionHandlerInterfaceを実装するクラスの作成。 2)セッションデータのライフサイクルとストレージ方法を定義するためのインターフェイス(オープン、クローズ、読み取り、書き込み、破壊、GCなど)の書き換え方法。 3)PHPスクリプトでカスタムセッションプロセッサを登録し、セッションを開始します。これにより、データをMySQLやRedisなどのメディアに保存して、パフォーマンス、セキュリティ、スケーラビリティを改善できます。

SessionIDは、ユーザーセッションのステータスを追跡するためにWebアプリケーションで使用されるメカニズムです。 1.ユーザーとサーバー間の複数のインタラクション中にユーザーのID情報を維持するために使用されるランダムに生成された文字列です。 2。サーバーは、ユーザーの複数のリクエストでこれらの要求を識別および関連付けるのに役立つCookieまたはURLパラメーターを介してクライアントに生成および送信します。 3.生成は通常、ランダムアルゴリズムを使用して、一意性と予測不可能性を確保します。 4.実際の開発では、Redisなどのメモリ内データベースを使用してセッションデータを保存してパフォーマンスとセキュリティを改善できます。

APIなどのステートレス環境でのセッションの管理は、JWTまたはCookieを使用して達成できます。 1。JWTは、無国籍とスケーラビリティに適していますが、ビッグデータに関してはサイズが大きいです。 2.cookiesはより伝統的で実装が簡単ですが、セキュリティを確保するために慎重に構成する必要があります。

セッション関連のXSS攻撃からアプリケーションを保護するには、次の測定が必要です。1。セッションCookieを保護するためにHTTPonlyとセキュアフラグを設定します。 2。すべてのユーザー入力のエクスポートコード。 3.コンテンツセキュリティポリシー(CSP)を実装して、スクリプトソースを制限します。これらのポリシーを通じて、セッション関連のXSS攻撃を効果的に保護し、ユーザーデータを確保できます。

PHPセッションのパフォーマンスを最適化する方法は次のとおりです。1。遅延セッション開始、2。データベースを使用してセッションを保存します。これらの戦略は、高い並行性環境でのアプリケーションの効率を大幅に改善できます。

thesession.gc_maxlifettinginttinginphpdethinesthelifsessessiondata、setinseconds.1)it'sconfiguredinphp.iniorviaini_set()。 2)AbalanceSneededToAvoidPerformanceIssues andunexpectedLogouts.3)php'sgarbagecollectionisisprobabilistic、影響を受けたBygc_probabi

PHPでは、session_name()関数を使用してセッション名を構成できます。特定の手順は次のとおりです。1。session_name()関数を使用して、session_name( "my_session")などのセッション名を設定します。 2。セッション名を設定した後、session_start()を呼び出してセッションを開始します。セッション名の構成は、複数のアプリケーション間のセッションデータの競合を回避し、セキュリティを強化することができますが、セッション名の一意性、セキュリティ、長さ、設定タイミングに注意してください。


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

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