- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- PostgreSQL/開発/include/utils/palloc.h へ行く。
- 1 (2017-05-16 (火) 21:40:21)
- 2 (2017-05-16 (火) 22:14:41)
- 3 (2017-05-18 (木) 00:00:43)
- 4 (2017-05-18 (木) 22:50:59)
- 5 (2017-05-20 (土) 01:06:24)
- 6 (2017-05-20 (土) 10:21:14)
- 7 (2017-05-20 (土) 23:18:19)
- 8 (2017-05-21 (日) 10:40:03)
- 9 (2017-05-21 (日) 22:20:16)
- 10 (2018-02-04 (日) 22:32:14)
- 11 (2020-01-03 (金) 08:55:02)
概要 †
- メモリ操作のためのAPI
- メモリはchunkと呼ばれる塊単位で扱われ,context(chunkを管理)に紐づくようになっている
- contextは木構造で管理されており,上位のcontextを破棄することで,下位のcontextの領域もまとめて解放することができる
定義 †
マクロ †
MemoryContextAllocExtendedのフラグ †
マクロ名 | 説明 |
---|---|
MCXT_ALLOC_HUGE | |
MCXT_ALLOC_NO_OOM | |
MCXT_ALLOC_ZERO |
列挙型 †
構造体 †
MemoryContextCallback †
番号 | データ型 | フィールド | 説明 |
---|---|---|---|
1 | MemoryContextCallbackFunction | func | コールバック関数 |
2 | void* | arg | コールバック関数に渡される引数 |
3 | struct MemoryContextCallback | next | コールバック関数リストの次ノード。 コールバック関数はリスト構造で管理されており複数のコールバック関数を登録できる。 |
MemoryContext †
MemoryContextDataポインタの別名
// 引数1:アロケーションサイズ palloc0fast(sz)
参考 struct MemoryContextData - on doxygen.postgresql.org
関数 †
MemoryContextAlloc †
typedef struct MemoryContextData *MemoryContext;
- アロケーション処理は,AllocSetAlloc関数で行われる。
- 引数で指定されたメモリコンテキストに指定されたサイズのメモリ領域を確保する。
- チャンクリミットを超える場合は,新規にブロックが作成される。そうでない場合は,フリーリストから検索される。
- アクティブなアロケーションブロックにチャンクスペースがあれば,チャンクのポインタを返す。そうでない場合は,
- ブロックがなければ,新規にブロックを作成してチャンクのポインタを返す。
参考 - AllocSetAlloc() - on doxygen.postgresql.org
サンプル
// 引数1:アロケーション対象のコンテキスト // 引数2:割当てサイズ(byte) // 戻り値:メモリチャンクのポインタ extern void *MemoryContextAlloc(MemoryContext context, Size size);
MemoryContextAllocZero †
void memory_sample() { // 専用のコンテキストを作成 MemoryContext context = AllocSetContextCreate(CurrentMemoryContext, "mycontext", 0, 8 * 1024, 8 * 1024); MemoryContext oldcontext = NULL; // カレントコンテキストのスイッチ oldcontext = MemoryContextSwitchTo(context); // メモリチャンクが返される MyExtensionOptions *opt = (MyExtensionOptions*) MemoryContextAlloc(context, sizeof(MyExtensionOptions)); // pallocは,内部でCurrentMemoryContextを使う // MyExtensionOptions *opt = (MyExtensionOptions*)palloc(sizeof(MyExtensionOptions)); opt->optcontext = ForeignTableRelationId; opt->optname = pstrdup("option1"); MemoryContextSwitchTo(oldcontext); MemoryContextDelete(context); }
MemoryContextAllocZeroAligned †
// 引数1:アロケーション対象のコンテキスト // 引数2:アロケーションサイズ(byte) // 戻り値:メモリチャンクのポインタ extern void *MemoryContextAllocZero(MemoryContext context, Size size);
MemoryContextAllocExtended †
// 引数1:アロケーション対象のコンテキスト // 引数2:アロケーションサイズ(byte) // 戻り値:メモリチャンクのポインタ extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size);
palloc †
// 引数1:アロケーション対象のコンテキスト // 引数2:アロケーションサイズ(byte) // 引数3:メモリアロケーション動作を決めるフラグ // 戻り値:メモリチャンクのポインタ extern void *MemoryContextAllocExtended(MemoryContext context, Size size, int flags);
palloc0 †
typedef struct MyExtensionOptions { const char *optname; Oid optcontext; } MyExtensionOptions; void memory_sample() { MemoryContext context = AllocSetContextCreate(CurrentMemoryContext, "mycontext", 0, 8 * 1024, 8 * 1024); MemoryContext oldcontext = NULL; oldcontext = MemoryContextSwitchTo(context); // 0クリア and メモリ確保失敗時にエラー報告 MyExtensionOptions *opt = (MyExtensionOptions*) MemoryContextAllocExtended(context, sizeof(MyExtensionOptions), MCXT_ALLOC_ZERO | MCXT_ALLOC_NO_OOM); opt->optcontext = ForeignTableRelationId; opt->optname = pstrdup("option1"); MemoryContextSwitchTo(oldcontext); MemoryContextDelete(context); }
palloc_extended †
// 引数1:アロケーションサイズ(byte) // 戻り値:メモリチャンクのポインタ extern void *palloc(Size size);
repalloc †
MyExtensionOptions *opt = (MyExtensionOptions*)palloc(sizeof(MyExtensionOptions)); // 以下と同様である // MyExtensionOptions * opt = MemoryContextAlloc(CurrentMemoryContext, sizeof(MyExtensionOptions));
pfree †
// 引数1:アロケーションサイズ(byte) // 戻り値:メモリチャンクのポインタ extern void *palloc0(Size size);
MemoryContextAllocHuge †
// 引数1:アロケーションサイズ(byte) // 引数2:メモリアロケーション動作を決めるフラグ // 戻り値:メモリチャンクのポインタ extern void *palloc_extended(Size size, int flags);
repalloc_huge †
// 引数1:メモリチャンクのポインタ // 引数2:再割り当てするサイズ(byte) // 戻り値:新しいメモリチャンクのポインタ extern void *repalloc(void *pointer, Size size);
MemoryContextSwitchTo †
char *optname = palloc(1 << 4); strcpy(optname, "hello world"); char *newoptname = repalloc(optname, 1 << 5); strcpy(newoptname, "hello world, hello postgres");
MemoryContextRegisterResetCallback †
// 引数1:メモリチャンクのポインタ extern void pfree(void *pointer);
MemoryContextStrdup †
// 引数1:アロケーション対象のコンテキスト // 引数2:アロケーションサイズ(byte) // 戻り値:メモリチャンクのポインタ extern void *MemoryContextAllocHuge(MemoryContext context, Size size);
pstrdup †
// 引数1:メモリチャンクのポインタ // 引数2:再割り当てするサイズ(byte) // 戻り値:新しいメモリチャンクのポインタ extern void *repalloc_huge(void *pointer, Size size);
pnstrdup †
// 引数1:スイッチするメモリコンテキスト // 戻り値:古い(スイッチする前の)メモリコンテキスト MemoryContext MemoryContextSwitchTo(MemoryContext context)
psprintf †
void memory_sample() { MemoryContext context = AllocSetContextCreate(CurrentMemoryContext, "mycontext", 0, 8 * 1024, 8 * 1024); MemoryContext oldcontext = MemoryContextSwitchTo(context); StringInfo strinfo = makeStringInfo(); appendStringInfo(strinfo, "%s", "hoge"); elog(NOTICE, "%s", strinfo->data); MemoryContextSwitchTo(oldcontext); MemoryContextDelete(context); }
pvsnprintf †
// 引数1:対象のメモリコンテキスト // 引数2:reset/delete時に呼ばれるコールバック関数 extern void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb);
サンプルプログラム †
// callback function void report_context_delete(void *arg) { MemoryContext context = (MemoryContext)arg; elog(NOTICE, "%s will be deleted", context->name); } void memory_sample() { MemoryContext context = AllocSetContextCreate(CurrentMemoryContext, "mycontext", 0, 8 * 1024, 8 * 1024); // コールバック関数の宣言と初期化 MemoryContextCallback callback = { report_context_delete, // Function Pointer context, // Argument }; // コールバック関数の登録 MemoryContextRegisterResetCallback(context, &callback); MemoryContext oldcontext = MemoryContextSwitchTo(context); char *optname = palloc(16); strcpy(optname, "hello world"); MemoryContextSwitchTo(oldcontext); // report_context_delete(context) is called MemoryContextDelete(context); }
参考・関連 †
- palloc.h - on doxygen.postgresql.org
- memnodes.h - on doxygen.postgresql.org
- mcxt.c - on doxygen.postgresql.org
- aset.c - on doxygen.postgresql.org
- NTTデータ 井久保さんによる解析資料 ~ メモリ管理 ~ - http://ikubo.x0.com/PostgreSQL/pg_source.htm
関連