メモリ管理内郚を芋る



良い䞀日

New Medioの CTOであるJonathan Bartlettによる蚘事の翻蚳に泚目したいず思いたす。 この蚘事は2004幎11月16日にibm.comで公開され、メモリヌ管理手法に焊点を圓おおいたす。 この蚘事の時代はITの基準によるず非垞に高いですが、その情報は基本的なものであり、メモリ割り圓おぞのアプロヌチ、その長所ず短所に぀いお説明しおいたす。 このすべおには、玠材のより良い同化のために、「自䜜」の実装が䌎いたす。



著者からの芁玄

動的メモリ割り圓おの決定、トレヌドオフ、実装

Linux開発者が利甚できるメモリ管理方法のアむデアを入手しおください。 これらのメ゜ッドはC蚀語に限定されず、他のプログラミング蚀語でも䜿甚されたす。 この蚘事では、手動アプロヌチ 手動 、参照カりント 参照カりント たたはプヌル プヌリング を䜿甚した半手動 半 手動 、およびガベヌゞコレクションを䜿甚した自動の䟋を䜿甚しお、メモリ管理の実行方法に぀いお詳しく説明したす。







メモリヌ管理が必芁な理由

メモリ管理は、プログラミングの最も基本的な分野の1぀です。 倚くのスクリプト蚀語では、メモリ管理に぀いお心配する必芁はありたせんが、これによりこのメカニズムの重芁性が䜎䞋するこずはありたせん。 メモリマネヌゞャの機胜ずその䜜業の耇雑さに関する知識は、効果的なプログラミングの鍵ずなりたす。 C / C ++などのほずんどのシステム蚀語では、開発者は自分で䜿甚するメモリを監芖する必芁がありたす。 この蚘事では、手動、半自動、および自動のメモリ管理方法に぀いお説明しおいたす。



メモリ管理が倧きな問題ではなかった時代がありたした。 䟋ずしお、Apple IIのアセンブラヌでの開発時間を思い出すこずができたす。 基本的に、プログラムはOSずは別にではなく、OSずずもに起動されたした。 システムず開発者の䞡方が任意のメモリを䜿甚できたす。 メモリの合蚈量を蚈算する必芁はありたせんでした。 すべおのコンピュヌタヌで同じでした。 そのため、メモリ芁件はかなり静的でした。メモリを遞択しお䜿甚する必芁がありたした。



それにもかかわらず、そのような単玔なコンピュヌタヌであっおも、特にプログラムの特定の郚分に必芁なメモリヌ量がわからない堎合は、問題を぀かむこずができたす。

メモリに関連する制限がある堎合、次のようなタスクを凊理するアプロヌチが必芁です。



 翻蚳者のメモ 埌で参照するために、このリストをメモリ芁件ずしお指定したしょう

メモリを怜玢/割り圓お/解攟するラむブラリは、アロケヌタず呌ばれたす。 プログラムの耇雑さが増すず、メモリ管理の耇雑さが増し、そのようなプログラムでのアロケヌタヌの圹割が増したす。 さたざたなメモリ管理方法を芋お、それらの長所ず短所、およびそれらが最も効果的な状況を考えおみたしょう。



アロケヌタヌCスタむル

C蚀語は、メモリ芁件のタスクを凊理する2぀の関数をサポヌトしおいたす。





物理メモリず仮想メモリ

プログラム内で割り圓おがどのように発生するかを理解するには、OSがプログラムにメモリを割り圓おる方法を把握する必芁がありたす。  翻蚳者のメモ プログラムは特定のOSで実行されるため、特定のプログラムに割り圓おるメモリ量を決定するのは圌女です実行䞭の各プロセスは、コンピュヌタヌの物理メモリ党䜓にアクセスできるず芋なしたす。 倚くのプロセスが同時に動䜜し、各プロセスがすべおのメモリにアクセスできないこずは明らかです。 しかし、プロセスが仮想メモリ 仮想メモリ を䜿甚するずどうなりたすか。



䟋ずしお、プログラムがメモリの629番目のセクションにアクセスするずしたす。 仮想メモリシステム 仮想メモリシステム は、デヌタが629番地のRAMに保存されるこずを保蚌したせん。実際、RAMであるずは限りたせん。RAMがいっぱいになった堎合、デヌタはディスクに転送されたす。 ぀たり ワヌスぞ。 メモリには、物理​​デバむスに察応するアドレスを栌玍できたす。 OSはWirth察応テヌブルを保存したす。 物理アドレス仮想アドレスから物理アドレス  ぞのアドレス。これにより、コンピュヌタはそのアドレスでの芁求  アドレス芁求 に正しく応答できたす 。 RAMに物理アドレスが栌玍されおいる堎合、OSはプロセスを䞀時的に䞭断し、デヌタをDISKにRAMからアップロヌドし、プロセスがDISKから機胜するために必芁なデヌタをロヌドし、プロセスを再起動したす。 したがっお、各プロセスは、それ自䜓が動䜜できる独自のアドレス空間を受け取り、それに割り圓おられたOSよりも倚くのメモリを受け取るこずができたす。



32ビットアプリケヌション x86アヌキテクチャでは、各プロセスは4ギガバむトのメモリで動䜜できたす。 珟時点では、ほずんどのナヌザヌはそのようなボリュヌムを所有しおいたせん。 スワップを䜿甚する堎合でも、プロセスごずに4 GB未満である必芁がありたす。 したがっお、プロセスがメモリにアンロヌドされるず、特定のスペヌスが割り圓おられたす。 このメモリの終わりは、 システムブレヌクず呌ばれたす 。 この境界を超えるず、割り圓おられおいないメモリ、぀たり ディスクたたはRAMぞの投圱なし。 したがっお、プロセスのメモリがブヌト時に割り圓おられたものからなくなるず、OSからより倧きなメモリを芁求する必芁がありたす。  マッピング 英語のマッピングから-リフレクション、プロゞェクションは、1察1の察応-぀たり、実際のデヌタが既に栌玍されおいる仮想アドレスディスク䞊のアドレスに異なるアドレスが栌玍されおいるこずを意味する数孊甚語です



UNIXベヌスのオペレヌティングシステムには、远加のメモリレむアりトのための2぀のシステムコヌルがありたす。





ご芧のずおり、プロセスメモリを拡匵するには、 brkたたはmmapの単玔な呌び出しを䜿甚できたす。 さらにテキストではbrkが䜿甚されたす 最もシンプルで䞀般的なツヌルです。



シンプルなアロケヌタヌの実装

Cプログラムを曞いたのであれば、おそらくmallocやfreeなどの関数を䜿甚したでしょう。 確かにあなたはそれらの実装に぀いおも考えおいたせんでした。 このセクションでは、これらの関数の簡単な実装を瀺し、それらがメモリ割り圓おにどのように関䞎するかを説明したす。

たずえば、このリストが必芁です。 それをコピヌしおmalloc.cずいうファむルに貌り付けたす。 少し埌で分析したす。

2぀の簡単な機胜に関連付けられおいるほずんどのオペレヌティングシステムでメモリを割り圓おたす。



アロケヌタヌを初期化するmalloc_init関数を宣蚀したす。 これは、アロケヌタを初期化枈みずしおマヌクし、メモリ内の最埌の有効なアドレスを芋぀けお぀たり、割り圓おに䜿甚できる、このメモリの先頭にポむンタを蚭定するずいう3぀のこずを意味したす。 これを行うには、3぀のグロヌバル倉数を宣蚀したす。



コヌドリスト1 アロケヌタヌのグロヌバル倉数

int has_initialized = 0; void *managed_memory_start; void *last_valid_address;
      
      







䞊蚘のように、ラベル付きメモリの「゚ッゞ」最埌の有効なアドレスにはいく぀かの名前がありたす-System breakたたはCurrent breakです。 ほずんどのUnixラむクシステムでは、 sbrk0関数を䜿甚しお珟圚のシステムブレヌクを芋぀けたす。 sbrkは、 珟圚のブレヌクを匕数で枡されたnバむトだけプッシュしたす。その埌、 珟圚のブレヌクは新しい倀を取りたす。 sbrk0を呌び出すず、単に珟圚のシステムが返されたす 。 珟圚のブレヌクを探しお倉数を初期化するmallocのコヌドを蚘述したす。

コヌドリスト2 アロケヌタヌの初期化

 /* Include the sbrk function */ #include <unistd.h> void malloc_init() { /*  (  )    */ last_valid_address = sbrk(0); /*     ,      *     last_valid_address */ managed_memory_start = last_valid_address; /*  ,    */ has_initialized = 1; }
      
      





適切に管理するには、割り圓おられたメモリず解攟されたメモリを監芖する必芁がありたす。 メモリの䞀郚に察しおfreeを呌び出した埌、メモリを「未䜿甚」ずしおマヌクする必芁がありたす。 これは、 mallocが呌び出されたずきに空きメモリを芋぀けるために必芁です。 したがっお、 mallocが返すメモリの各郚分の先頭は次の構造になりたす。

コヌドリスト3 メモリ制埡ブロックの構造

 struct mem_control_block { int is_available; int size; };
      
      





この構造䜓ぞのポむンタヌを返す malloc関数を呌び出すず、この構造䜓が干枉するず掚枬できたす。  翻蚳者のコメント ポむンタがこの構造の先頭に蚭定されおいる堎合、このメモリに曞き蟌むず、割り圓おられたメモリ量に関する情報が倱われたすすべおが非垞に簡単に解決されたす-非衚瀺にする必芁がありたす、぀たり、ポむンタをメモリに戻す、この構造のすぐ埌ろにありたす。 ぀たり 実際、情報を栌玍しおいない領域ぞのポむンタを返し、デヌタを「曞き蟌む」こずができたす。 ポむンタヌが枡されるfree呌び出しが行われるず、特定のバむト数具䜓的にはsizeof mem_control_blockを巻き戻しお、この構造のデヌタをさらに怜玢するために䜿甚したす。



たず、メモリの解攟に぀いお説明したしょう。なぜなら、 このプロセスは匷調衚瀺よりも簡単です。 メモリを解攟するために必芁なのは、パラメヌタずしお枡されたポむンタをfree関数に取り、 sizeof struct mem_control_blockバむトに戻し、メモリを空きずしおマヌクするこずです。 コヌドは次のずおりです。

コヌドリスト4 メモリを解攟する

 void free(void *firstbyte) { struct mem_control_block *mcb; /*          * mem_control_block */ mcb = firstbyte - sizeof(struct mem_control_block); /*     */ mcb->is_available = 1; /*  ! */ return; }
      
      





ご芧のずおり、この䟋では、リリヌスは䞀定の時間で行われたす。 実装は非垞に簡単です。 遞択では、もう少し難しくなりたす。 䞀般的な甚語でアルゎリズムを怜蚎しおください。

コヌドリスト5 アロケヌタヌアルゎリズムの擬䌌コヌド

 1.      ,   . 2.  sizeof(struct mem_control_block)    ; 3.   managed_memory_start. 4.      last_valid address? 5.  : A.                  . 6.  : A.    ?( mem_control_block->is_available == 1)? B.  : I) -    (mem_control_block->is_available >=  )? II)  : a.     (mem_control_block->is_available = 0) b.    mem_control_block    III)   : a.   "size"   b.    4 C.  : I)   "size"   II)    4
      
      





党䜓のポむントは、無料のサむトを芋぀けるためのメモリからの䞀皮の「りォヌク」です。 コヌドを芋おください

コヌドリスト6 ワヌクフロヌの実装

 void *malloc(long numbytes) { /*     */ void *current_location; /*      * memory_control_block */ struct mem_control_block *current_location_mcb; /*       .       0 */ void *memory_location; /* ,      */ if(! has_initialized) { malloc_init(); } /*     memory * control block,    malloc  *   .       */ numbytes = numbytes + sizeof(struct mem_control_block); /*  memory_location 0      */ memory_location = 0; /*      ()  */ current_location = managed_memory_start; /*      */ while(current_location != last_valid_address) { /*   current_location  current_location_mcb *  .  current_location_mcb *     ,  * current_location    t */ current_location_mcb = (struct mem_control_block *)current_location; if(current_location_mcb->is_available) { if(current_location_mcb->size >= numbytes) { /* !    ... */ /*   ,    -     */ current_location_mcb->is_available = 0; /*     */ memory_location = current_location; /*   */ break; } } /*    ,         ,   */ current_location = current_location + current_location_mcb->size; } /*        ,       */ if(! memory_location) { /* Move the program break numbytes further */ sbrk(numbytes); /*  , last_valid_address   */ memory_location = last_valid_address; /*   last valid address  * numbytes  */ last_valid_address = last_valid_address + numbytes; /*   mem_control_block */ current_location_mcb = memory_location; current_location_mcb->is_available = 0; current_location_mcb->size = numbytes; } /*     (   ). *   memory_location     * mem_control_block */ /*     mem_control_block */ memory_location = memory_location + sizeof(struct mem_control_block); /*   */ return memory_location; }
      
      





これがメモリマネヌゞャです。 次に、プログラムで䜿甚するためにアセンブルする必芁がありたす。

mallocに䌌たアロケヌタヌを構築するには、次のコマンドを入力する必芁がありたす reallocなどの関数には觊れたせんでしたが、 mallocおよびfreeが最も重芁です。

コヌドリスト7 コンパむル

 gcc -shared -fpic malloc.c -o malloc.so
      
      





出力で、 malloc.soファむルを取埗したす。これはラむブラリであり、コヌドが含たれおいたす。

Unixシステムでは、システムの代わりにアロケヌタヌを䜿甚できたす。 これは次のように行われたす。

コヌドリスト8 暙準mallocの眮き換え

 LD_PRELOAD=/path/to/malloc.so export LD_PRELOAD
      
      





LD_PRELOADは環境倉数です 。 このラむブラリがアプリケヌションによっおロヌドされる前に、ラむブラリに含たれる文字を決定するために、動的リンカヌによっお䜿甚されたす。 これは、動的ラむブラリでのシンボルの重芁性を匷調しおいたす。 したがっお、珟圚のセッションの䞀郚ずしお䜜成されるアプリケヌションは、先ほど䜜成したmallocを䜿甚したす。 䞀郚のアプリケヌションはmallocを䜿甚したせんが、これはルヌルではなく䟋倖です。 reallocのようにアロケヌタヌを䜿甚しおいる人や、mallocの内郚動䜜に぀いおたったく知らない人は、陥りやすいでしょう。 AshシェルashはこのようなシステムのUNIXコマンドシェルですは、 mallocアロケヌタヌでうたく機胜したす。



mallocが䜿甚されおいるこずを確認したい堎合は、関数の先頭にwrite呌び出しを远加できたす。



機胜面では、メモリマネヌゞャ メモリマネヌゞャ には倚くの芁望が残されおいたすが、䜜業を瀺す䟋ずしおは玠晎らしいものです。 その欠点のうち、次の点に泚意する必芁がありたす。



他のmalloc実装

長所ず短所の䞡方を持぀他の倚くのmalloc実装がありたす。 アロケヌタヌを蚭蚈する際に考慮すべき倚くの基準がありたす。



たずえば、アロケヌタの堎合、プラスはメモリのクむックリリヌスであり、マむナスは遅い割り圓おです。 たた、Wirthを操䜜するためのプリミティブアルゎリズムが原因です。 メモリ、それは倧きなオブゞェクトに最適です。



アロケヌタヌには倚くの皮類がありたす。 それらのいく぀かを次に瀺したす。



これらは、倚くのアロケヌタヌの䞭で最も有名です。 アプリケヌションで特別なメモリ割り圓おが必芁な堎合は、芁件に基づいお機胜する自䜜カスタムアロケヌタを䜜成できたす。 ずにかく、アロケヌタヌの抂念に慣れおいない堎合、自己蚘述の実装は利益をもたらすよりも倚くの頭痛の皮を䜜成したす。 サブゞェクト領域の詳现に぀いおは、次の本を読むこずをお勧めしたす。 ドナルドクヌヌスプログラミングアヌト1基本アルゎリズム -セクション2.5動的メモリ割り圓お。 もちろん玠材は時代遅れであり、Wirthでの䜜業はそこでは圱響を受けたせん。 環境メモリですが、アルゎリズムのベヌスは倉曎されおいたせん。



C ++では、 new挔算子のオヌバヌロヌド挔算子を䜿甚しお、クラスたたはテンプレヌトにアロケヌタヌを実装できたす。 Andrei Alexandrescuは著曞Modern C ++ Programmingで小さなアロケヌタヌオブゞェクトに぀いお説明しおいたす第4章小さなオブゞェクトをメモリに配眮する。



mallocを䜿甚した配垃の欠点

メモリマネヌゞャに欠陥があるだけでなく、他の実装にも存圚したす。 mallocで管理するこずは、デヌタを長期間保存し、簡単にアクセスできるプログラムにずっおは非垞に危険なこずです。 動的に割り圓おられたメモリぞの倚くの参照があるため、い぀解攟する必芁があるかを芋぀けるのは困難です。 倉数の有効期間たたはメモリの䞀郚を操䜜する時間が関数のスコヌプロヌカル倉数によっお制限されおいる堎合、マネヌゞャは通垞簡単に仕事をしたすが、プログラム党䜓でメモリが䜿甚されるグロヌバル倉数の堎合、タスクは倧幅になりたす難しい。 たた、倚くのAPIは完党には蚘述されおおらず、プログラム自䜓たたは呌び出された関数で、誰がメモリを管理する責任があるのか​​が明確になりたせん。

このような問題のため、倚くのプログラムは独自のルヌルに埓っおメモリを操䜜したす。 堎合によっおは、コンピュヌティングコンポヌネントよりもメモリの割り圓おず解攟に倚くの操䜜 箄Translator テキスト内の「より倚くのコヌド」が費やされるこずを瀺すこずがありたす。 したがっお、メモリを管理する別の方法を怜蚎したす。



メモリ管理ぞの半自動アプロヌチ




参照カりント

参照カりントは、远加のコヌドを必芁ずするメモリを操䜜する半自動の方法であり、メモリが䜿甚されなくなった時期を远跡できたせん。 参照カりントがこれを行いたす。



䜜業のメカニズムは次のずおりです。動的に割り圓おられたメモリごずに、それぞの参照の数を栌玍するフィヌルドがありたす。 このメモリを参照する倉数がプログラムに衚瀺されるず、カりンタヌがむンクリメントされたす。 そしおその逆-このメモリを参照する倉数が枛少するず、カりンタヌが枛少したす。 カりンタヌをデクリメントするず、チェックが発生したす。リンクの数が0の堎合、メモリは解攟されたす。



このメモリを参照する各リンクは、単にカりンタを増枛したす。 これにより、䜿甚䞭のメモリクリヌニング状況が回避されたす。 いずれにせよ、このタむプの「カりントされた」構造で䜜業しおいる堎合、リンクのカりントを担圓する関数を䜿甚するこずを忘れないでください。 たた、組み蟌み関数ずサヌドパヌティラむブラリは、 参照カりントを䜿甚したり、独自の動䜜メカニズムを䜿甚できない堎合がありたす。



このメカニズムを実装するには、2぀の機胜で十分です。 1぀目は参照カりンタを増やし、2぀目は枛少しおれロに達するずメモリを解攟したす。

たずえば、リンクカりント関数は次のようになりたす。

リスト9. 参照カりントの仕組み

 /* /  */ /*      - Reference counter */ struct refcountedstruct { int refcount; } /*   (  ),  *       refcountedstruct */ /*    */ /*   */ void REF(void *data) { struct refcountedstruct *rstruct; rstruct = (struct refcountedstruct *) data; rstruct->refcount++; } /*   */ void UNREF(void *data) { struct refcountedstruct *rstruct; rstruct = (struct refcountedstruct *) data; rstruct->refcount--; /*  ,     */ if(rstruct->refcount == 0) { free(rstruct); } }
      
      





REFずUNREFはより耇雑になる可胜性がありたす-それはすべおあなたが远求する目暙に䟝存したす。 たずえば、マルチスレッドアプリケヌションにロックを远加するこずができたす。 次に、 refcountedstructに 、メモリを解攟する関数ぞのポむンタを远加する必芁がありたすオブゞェクト指向蚀語のデストラクタなど-これは、構造䜓にポむンタが含たれおいる堎合に必芁です

REFおよびUNREFを䜿甚する堎合は、ポむンタヌを割り圓おるずきに次の芏則に埓う必芁がありたす。



再カりントされた構造を受け入れる関数の堎合、次の芏則が䜿甚されたす。



別の小さな䟋を次に瀺したす。

 /* EXAMPLES OF USAGE */ /*    refcounted */ struct mydata { int refcount; /*   refcountedstruct */ int datafield1; /*     */ int datafield2; /*  ,    */ }; /*     */ void dosomething(struct mydata *data) { REF(data); /*   */ /*    */ UNREF(data); } struct mydata *globalvar1; /*     ,    * refcount ..    .  */ void storesomething(struct mydata *data) { REF(data); /*    */ globalvar1 = data; REF(data); /* ref     */ UNREF(data); /*   */ }
      
      





なぜなら 参照カりントは非垞に簡単なメカニズムであるため、倚くの開発者はサヌドパヌティのラむブラリを避けお自分で実装したす。 ただし、それらの実装は、メモリの割り圓おず解攟専甚のmallocやfreeなどのアロケヌタヌに基づいおいたす。 参照カりントは、 Perlなどの高レベル蚀語でも䜿甚されたす。 これらの矩務は蚀語自䜓に割り圓おられおいるため、もちろん拡匵したい堎合を陀き、䜕も心配する必芁はありたせん。 もちろん、リンクカりントは䜜業の速床をわずかに䜎䞋させたすが、開発に少しのセキュリティずシンプルさを远加したす。 䞻な利点を考慮しおください。



欠点もありたす



C ++は、 参照カりントず同じくらい苊劎しおポむンタを操䜜するスマヌトポむンタを䜿甚しお 、゚ラヌの可胜性を枛らすこずができたす 。スマヌトポむンタヌを実行しおいないレガシコヌドの所有者たずえば、Cラむブラリでのリンケヌゞの堎合、このコヌドをさらに䜿甚するずひどい混乱に぀ながり、スマヌトポむンタヌによっお制埡されるコヌドに比べおコヌドが耇雑で混乱したす。したがっお、通垞はC ++プロゞェクトでのみ䜿甚されたす。スマヌトポむンタヌを䜿甚する堎合は、Modern C ++ ProgrammingAndrei Alexandreksu著の「スマヌトポむンタヌ」の章を読むだけで枈みたす。



メモリプヌル

メモリプヌルは、半自動メモリ管理の別の方法です。特定のステヌゞ/フラグメントステヌゞを通過するプログラムのプロセスを自動化したす実行。プログラムの各段階で、プログラムに必芁なスペヌスの量がわかっおいたす。たずえば、接続に倧量のメモリが割り圓おられるサヌバヌプロセスです。その最倧寿呜は接続の寿呜ず䞀臎したす。同じApache-各接続は個別のステヌゞであり、独自のメモリプヌルがありたす。フラグメントが実行されるず、メモリは即座に解攟されたす。



「プヌル」管理モデルでは、各メモリ割り圓おは、メモリが割り圓おられる特定のプヌルを参照したす。コメント翻蚳者char型のロヌカル倉数が5぀ある関数を想像しおください。぀たりこの機胜を実行する堎合、5バむトのメモリが必芁になるこずが事前にわかっおいたす。぀たりこの関数の本䜓は、実行䞭にプログラムが通過する段階に䌌おおり、その䞋に5バむトの固定サむズのメモリをすぐに割り圓おるこずができたす。これにより、倉数が関数に衚瀺されるため、メモリの怜玢ず「カット」にかかる時間が節玄され、垞に十分なメモリがあるこずが保蚌されたす。各プヌルには独自の有効期間がありたす。 Apacheでは、プヌルサヌバヌの時間、接続期間、芁求凊理時間などに等しいラむフタむムがありたす。したがっお、接続のサむズを超えないメモリを必芁ずする䞀連の機胜がある堎合、接続プヌルから単玔に割り圓おられ、䜜業が完了するず、自動的にリリヌスされたす。さらに、䞀郚の実装では、プヌルがクリアされる前にいく぀かのアクションを実行するために呌び出されるクリヌンアップ関数OOPのデストラクタのようなものを登録できたす。



プログラムでプヌルを䜿甚するには、単にobstackGNU -libcたたはApache Protable RuntimeApache実装を䜿甚できたす。obstackの利点これは、すべおのLinuxディストリビュヌションにデフォルトで付属しおいるものです。たた、Apache Portable Runtimeは倚くのプラットフォヌムで䜿甚する機䌚です。実装の詳现に぀いおは、蚘事の最埌にリンクがありたす。



次の「工倫された」䟋は、obstackの䜿甚法を瀺しおいたす。

リスト11. obstackを䜿甚した䟋

 #include <obstack.h> #include <stdlib.h> /*   obstack  */ /*  obstack  (xmalloc *    malloc,    ,      (..   ) */ #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free /* Pools */ /* Only permanent allocations should go in this pool */ struct obstack *global_pool; /*  pool   (per-connection) */ struct obstack *connection_pool; /*     (per-request) */ struct obstack *request_pool; void allocation_failed() { exit(1); } int main() { /*   */ global_pool = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init(global_pool); connection_pool = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init(connection_pool); request_pool = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init(request_pool); /*    */ obstack_alloc_failed_handler = &allocation_failed; /*   */ while(1) { wait_for_connection(); /*     */ while(more_requests_available()) { /*   */ handle_request(); /*       (request pool) */ obstack_free(request_pool, NULL); } /*    -    */ obstack_free(connection_pool, NULL); } } int handle_request() { /*  ,        (request pool) */ int bytes_i_need = 400; void *data1 = obstack_alloc(request_pool, bytes_i_need); /*     */ /*   */ return 0; }
      
      





原則ずしお、各ステヌゞが完了するず、obstackのメモリヌが解攟されたす。ただし、実行プロセス䞭にステヌゞに割り圓おられおいるよりも倚くのメモリが必芁な堎合、接続たたはグロヌバル倉数のラむフタむムに匹敵するobstackラむフタむムが増加する可胜性があるこずに泚意しおください。堎合obstack_freeパラメヌタを指定しお呌び出しNULL、その埌、すべおがリリヌスされたすobstackを。他のパラメヌタヌを䜿甚した呌び出しはたれです。

プヌルを䜿甚する利点



欠点の䞭で、次の点に泚意するこずができたす。



ガベヌゞコレクタガベヌゞコレクション

ガベヌゞコレクションは -完党に自動怜出し、メモリから未䜿甚のオブゞェクトを陀去するこずです。メモリが特定のしきい倀を䞋回るず匕き継ぎたす。圌はプログラムを運営し、「基本的な」デヌタ、に枡す通垞、最初のもの-スタック積み重ね、グロヌバル倉数グロヌバル倉数アンずレゞスタレゞスタコレクタヌは、プログラムでのこのデヌタの䜿甚を远跡しようずしおいたす。このデヌタぞのリンクが芋぀かった堎合、それらにアクセスしたせん。そうでない堎合、メモリは消去され、再利甚できたす。より効率的なメモリ管理のために、倚くのコレクタヌは構造ぞのポむンタの䞀皮の「ベヌス」を自由に䜿甚できるため、正しく動䜜するには蚀語の䞀郚である必芁がありたす。

コレクタヌのタむプ



保守党sboschik ハンス・ベヌムハンス・ベヌムによっおは以来、コレクタヌの䞭で最も人気の䞀぀です無料で、保守的で増分的です。-enable-redirect-mallocフラグを䜿甚しおアプリケヌションを構築する堎合、システムアロケヌタの代わりずしお独自のAPIの代わりにmalloc / freeを䜿甚しお非垞によく䜿甚できたす。実際に、それは英語でトリックスず同じである。トリック-トリック、トリックアロケヌタヌで䜿甚したLD_PRELOADを䜿甚したす。この堎合のみ、コレクタヌをほずんどすべおのプログラムにリンクするのに圹立ちたす。プログラムでメモリリヌクが発生しおいるず思われる堎合は、このコレクタを䜿甚しお、消費されるメモリの量を枛らすこずができたす。倚くの人々は、Mozilaが最初に登堎した時代にこの手法を䜿甚したした。その埌、メモリリヌクで深刻な病気になりたした。コレクタヌは、WindowsずLinuxの䞡方で機胜したす。

コレクタヌの利点



短所



たずめ

これは劥協の䞖界ですパフォヌマンス、䜿いやすさ、実装のしやすさ、マルチスレッドずの互換性。倚くのメモリ管理テンプレヌトがありたす-プロゞェクトの芁件を確実に満たすものもありたす。各テンプレヌトには長所ず短所がありたす。暙準的な方法はほずんどのプログラムに適しおいたすが、プロゞェクトに固有の芁件がある堎合は、代替方法の知識が圹立ちたす。結論ずしお、この蚘事で説明したメモリ管理方法の比范衚を玹介したす。

è¡š1メモリ割り圓おのアプロヌチの比范

アプロヌチ 割り圓お速床 リリヌス速床 キャッシュの局所性 適甚性 real time SMP
Custom allocator
Simple allocator いや いや
GNU malloc いや
Hoard いや はい
Reference counting - - ( malloc )
Pooling ( malloc )
Garbage collection ( ) いや
Incremental garbage collection いや
Incremental conservative garbage collection いや


:





All Articles