- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- PostgreSQL/解析/MemoryContext へ行く。
Memory Context †
- フラットなメモリ空間を構造化して管理するための機能であり、backendで用いられる。
- メモリコンテキストの初期化時、TopMemoryContextとErrorContextが作成される。この他、トップレベルのメモリコンテキストには、PostmasterContext、CacheMemoryContext、MessageContext、TopTransactionContext、CurTransactionContextがあり、TopMemoryContextは、全てのメモリコンテキストの親である。
参考 - メモリコンテキストはツリーの階層で管理され、ノードは1つの親ノードを持てる。
あるコンテキストを削除することで、そのコンテキストの子である一連のメモリコンテキストを削除したりすることができる。 - メモリコンテキストはそれぞれ独立したメモリ領域を持ち、親子の関連はメモリ使用域とは関係ない。
Memory Contextの構造と操作 †
Memory Contextを使用することでメモリ管理が容易になり、メモリリークなどのバグを減らせる。
基本的なメモリコンテキストの操作イメージは以下の図の通りである。
Memory Contextに関連する構造体 †
MemoryContextData †
typedef struct MemoryContextData { NodeTag type; /* identifies exact kind of context */ /* these two fields are placed here to minimize alignment wastage: */ bool isReset; /* T = no space alloced since last reset */ bool allowInCritSection; /* allow palloc in critical section */ const MemoryContextMethods *methods; /* virtual function table */ MemoryContext parent; /* NULL if no parent (toplevel context) */ MemoryContext firstchild; /* head of linked list of children */ MemoryContext prevchild; /* previous child of same parent */ MemoryContext nextchild; /* next child of same parent */ const char *name; /* context name (just for debugging) */ const char *ident; /* context ID if any (just for debugging) */ MemoryContextCallback *reset_cbs; /* list of reset/delete callbacks */ } MemoryContextData;
参考struct MemoryContextData - https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/tags/REL_12_1
- メモリコンテキストは、parent(親)、childlen(子ノード)、prevchild(同階層の前のノード)、nextchild(同階層の次のノード)へのポインタを持っている。
- メモリアロケーションの操作は、struct MemoryContextMethodsの関数群が担う。
MemoryContextMethods †
メモリコンテキストの具象実装である。
typedef struct MemoryContextMethods { void *(*alloc) (MemoryContext context, Size size); /* call this free_p in case someone #define's free() */ void (*free_p) (MemoryContext context, void *pointer); void *(*realloc) (MemoryContext context, void *pointer, Size size); void (*reset) (MemoryContext context); void (*delete_context) (MemoryContext context); Size (*get_chunk_space) (MemoryContext context, void *pointer); bool (*is_empty) (MemoryContext context); void (*stats) (MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals); #ifdef MEMORY_CONTEXT_CHECKING void (*check) (MemoryContext context); #endif } MemoryContextMethods;
参考struct MemoryContextMethods - https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/tags/REL_12_1
例えば、デフォルトで使われるAllocSetは以下の関数で構成される。
static const MemoryContextMethods AllocSetMethods = { AllocSetAlloc, AllocSetFree, AllocSetRealloc, AllocSetReset, AllocSetDelete, AllocSetGetChunkSpace, AllocSetIsEmpty, AllocSetStats #ifdef MEMORY_CONTEXT_CHECKING ,AllocSetCheck #endif };
参考MemoryContextMethods AllocSetMethods - https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/tags/REL_12_1
AllocSetContext †
最も標準的なMemoryContextの実装はAllocSetである。
以下はAllocSetの構造外観を図示したものである。
(詳細は、aset.cを参照して欲しい)
参考 src/backend/utils/mmgr/aset.c - https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/tags/REL_12_1
- メモリ領域をblock(AllocBlockData)とchunk(AllocChunkData)という概念で管理する。
blockは、1つまたは複数のchunkから構成される。chunkは、pallocごとに実際に獲得されるメモリ領域であり、pallocで返されるメモリ番地はchunkのデータ部である。