メモリ管理のお勉強

  • HEAP領域とSTACK領域の間の未使用領域は、下記の領域に使われる
    • 共有ライブラリのロード領域
    • メモリ・マップト・ファイル用領域
    • プロセス間共有メモリ用領域
    • メモリ・マップト・I/O用領域
    • メモリ・マップトによる追加HEAP領域
      • 小さなサイズをmallocをしたときはHEAP領域に確保されるが、大きなサイズのメモリをmallocしたときはメモリマップ領域に確保される(glibcの場合)
      • すべてmmapにするとメモリのフラグメンテーションがおきないが、mmapは重いしページサイズ単位しか扱えない。
  • 32bit環境では論理メモリが2^32=4GBまでしか確保できない。このうちOSがメモリの上位1or2GBを使うので、実際にはアプリは3or2GBまでしかメモリは使えない。64bit環境になると、もっと使えるようになる。
  • HEAP領域は下に(上位アドレス方向)、STACK領域は上に(下位アドレス方向)伸びていく
  • Linuxでは/proc/PID/mapsにメモリのマップが書いてある
  • メモリ確保の場所
    • HEAP
      • HEAP領域がたりないときは、OSがbrkシステムコールを発行することによってHEAP領域を延ばす
      • brkによってOSから確保したメモリは、その領域が解放されたときにOSにメモリが返却されるとは限らない。フラグメンテーションが起きているときは返却されない。
      • →解放後、そのメモリにアクセスしても落ちないことがある
    • mmap
      • メモリ・マップト・ファイル用領域に確保される。その領域が解放されたときに必ずOSにメモリが返却される。
      • →解放後、そのメモリにアクセスすると落ちる。
    • スタック
      • 各スレッドにスタックが割り当てられ、そのスレッドで使う変数はそのスタック内で領域の確保/解放を繰り返す。
      • 物理メモリは実際に割り当てられたメモリを実際に使うときに割り当てられるが、一度物理メモリが割り当てられると、そのスレッドが終了するまでその物理メモリは解放されない
      • 同時に使っているスタック領域が多いと、多くの物理メモリが割り当てられることになる
  • malloc
    • 要求を満たす空き領域があれば要求サイズ分切り出す。なければOSからまとまったサイズのメモリを取得してから切り出す
    • HEAPまたはメモリマップ領域から切り出される。
    • WinではmallocはHeapAllocに割り当てられるが、HeapAllocの実装は不明。
  • 物理メモリの確保
    • linuxでは物理メモリの大きさとは関係なく、要求したサイズの論理メモリ領域が確保できる
      • ただし、物理メモリが不足するとOOM(Out Of Memory)-Killerがプロセスを勝手に殺すので注意!
  • フラグメンテーション
    • 連続領域を確保するためにOSからメモリ取得を繰り返すと、ヒープ領域が拡大し、メモリ・リークしていないのに、メモリ使用量が増大していくことがある。
    • 最初にある程度のメモリを確保し、そこから切り出して使うようにすることでフラグメンテーションを避けることができる。
  • malloc, freeのラッパーをつくるなどしてメモリ使用の統計をとると、最初に確保するメモリの目安やメモリリークのチェックを行うことができる
  • Memory Mapped File
    • ファイルI/Oをread/write APIを使わずにメモリアクセスで行う
    • I/Oエラー時は、例外が発生する(と思われる)ので、read/writeに比べて、ハンドリングが面倒。SIGSEGなどの例外をキャッチする必要がある。
  • アラインメント
    • データは、自身のデータ長で割り切れるアドレスに配置すること!
      • 32bitデータは4で割り切れるアドレス
      • 128bitデータは16で割り切れるアドレス
    • 構造体のPACKもよくない★
  • はじめて読む486
  • 省メモリプログラミング ― メモリ制限のあるシステムのためのソフトウェアパターン集 (ピアソンエデュケーション)