- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2020-01-04T04:57:53+00:00","default:haikikyou","haikikyou")
#author("2020-01-04T11:20:18+00:00","default:haikikyou","haikikyou")
[[PostgreSQL/解析]]
#contents
* Memory Context [#ed0f9858]
-フラットなメモリ空間を構造化して管理するための機能であり、backendで用いられる。
-メモリコンテキストの初期化時、TopMemoryContextとErrorContextが作成される。この他、トップレベルのメモリコンテキストには、PostmasterContext、CacheMemoryContext、MessageContext、TopTransactionContext、CurTransactionContextがあり、TopMemoryContextは、全てのメモリコンテキストの親である。~
&label(warn){参考};
-- [[src/backend/utils/mmgr/README>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/mmgr/README;h=7e6541d0dee2783065b66cd6482478c298dec7a9;hb=refs/heads/REL_12_STABLE]] - &size(11){&color(gray){https://git.postgresql.org/gitweb/?p=postgresql.git;a=tree;h=refs/heads/REL_12_STABLE};};
--[[src/backend/utils/mmgr/mcxt.c>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/mmgr/mcxt.c;h=b07be1223698a094f1b3a41ac59370d2b3d1cdb7;hb=refs/heads/REL_12_STABLE]] - &size(11){&color(gray){https://git.postgresql.org/gitweb/?p=postgresql.git;a=tree;h=refs/heads/REL_12_STABLE};};
-- [[src/backend/utils/mmgr/README>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/mmgr/README;h=7e6541d0dee2783065b66cd6482478c298dec7a9;hb=refs/heads/REL_12_STABLE]] - &size(11){&color(gray){https://git.postgresql.org/gitweb/?p=postgresql.git;a=tree;h=refs/heads/REL_12_STABLE};};
- メモリコンテキストはツリーの階層で管理される。ノードは1つの親に属する。
- メモリコンテキストは、それぞれ独立したメモリ領域を持つ。親子の関連は、メモリ使用量とは関係ない。
* Memory Contextの操作 [#c06be0e1]
- メモリコンテキストはツリーの階層で管理され、ノードは1つの親ノードを持てる。~
あるコンテキストを削除することで、そのコンテキストの子である一連のメモリコンテキストを削除したりすることができる。
- メモリコンテキストはそれぞれ独立したメモリ領域を持ち、親子の関連はメモリ使用域とは関係ない。
* Memory Contextの構造と操作 [#c06be0e1]
Memory Contextを使用することで、メモリ管理が容易になり、メモリリークのバグも減らせる。~
基本的なメモリコンテキストの操作は以下の図の通りである。
Memory Contextを使用することでメモリ管理が容易になり、メモリリークなどのバグを減らせる。~
基本的なメモリコンテキストの操作イメージは以下の図の通りである。
&ref(./memory-context-overview.png,100%);
** Memory Contextに関連する構造体 [#p796ab86]
*** MemoryContextData [#e7da4a65]
#geshi(c){{{
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;
}}}
&label(warn){参考};[[struct MemoryContextData>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/nodes/memnodes.h;h=dbae98d3d9f28522a203fe81d21d7dd9810c6330;hb=refs/tags/REL_12_1#l57]] - &size(11){&color(gray){https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/tags/REL_12_1};};
- メモリコンテキストは、parent(親)、childlen(子ノード)、prevchild(同階層の前のノード)、nextchild(同階層の次のノード)へのポインタを持っている。
- メモリアロケーションの操作は、struct MemoryContextMethodsの関数群が担う。
*** MemoryContextMethods [#db0ec67d]
メモリコンテキストの具象実装である。
#geshi(c){{{
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;
}}}
&label(warn){参考};[[struct MemoryContextMethods>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/nodes/memnodes.h;h=dbae98d3d9f28522a203fe81d21d7dd9810c6330;hb=refs/tags/REL_12_1#l57]] - &size(11){&color(gray){https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/tags/REL_12_1};};
例えば、デフォルトで使われるAllocSetは以下の関数で構成される。
#geshi(c){{{
static const MemoryContextMethods AllocSetMethods = {
AllocSetAlloc,
AllocSetFree,
AllocSetRealloc,
AllocSetReset,
AllocSetDelete,
AllocSetGetChunkSpace,
AllocSetIsEmpty,
AllocSetStats
#ifdef MEMORY_CONTEXT_CHECKING
,AllocSetCheck
#endif
};
}}}
&label(warn){参考};[[MemoryContextMethods AllocSetMethods>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/mmgr/aset.c;hb=578a551f82f7ad746b36d98c401bdc92c136d664#l286]] - &size(11){&color(gray){https://git.postgresql.org/gitweb/?p=postgresql.git;a=shortlog;h=refs/tags/REL_12_1};};
* AllocSetContext [#y03a961f]
ベースとなるMemoryContextの実装は、AllocSetである。~
AllocSet
最も標準的なMemoryContextの実装はAllocSetである。~
以下はAllocSetの構造外観を図示したものである。~
(詳細は、aset.cを参照して欲しい)
&ref(./allocset-overview.png,90%);
&label(warn){参考}; [[src/backend/utils/mmgr/aset.c>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/mmgr/aset.c;hb=578a551f82f7ad746b36d98c401bdc92c136d664#l286]] - &size(11){&color(gray){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のデータ部である。
* 参考リンク [#zbd54bd5]
- [[PostgreSQL Internals>https://www.postgresqlinternals.org/chapter5/]] - &size(11){&color(gray){on https://www.postgresqlinternals.org/chapter5/};};