[PostgreSQL] memnode

src/include/nodes/memnodes.h


MemoryContextData

  • 이 구조체의 포인터 타입이 MemoryContext 이다

MemoryContextCounters

  • block을 여러 개의 chunk로 나누어 사용한다
  • 이 구조체의 각 필드를 counter 라고 한다
  • AllocSet
/*
 * MemoryContextCounters
 *      Summarization state for MemoryContextStats collection.
 *
 * The set of counters in this struct is biased towards AllocSet; if we ever
 * add any context types that are based on fundamentally different approaches,
 * we might need more or different counters here.  A possible API spec then
 * would be to print only nonzero counters, but for now we just summarize in
 * the format historically used by AllocSet.
 */
typedef struct MemoryContextCounters
{
    Size        nblocks;        /* Total number of malloc blocks */
    Size        freechunks;     /* Total number of free chunks */
    Size        totalspace;     /* Total bytes requested from malloc */
    Size        freespace;      /* The unused portion of totalspace */
} MemoryContextCounters;
  • nblocks - malloc으로 block만큼의 메모리를 할당받은 횟수. malloc으로 할당한 메모리를 block이라고 하는듯
  • freechunks - 사용 가능한 메모리 chunk 개수. block을 chunk로 쪼개서 관리하는듯
  • totalspace - malloc으로 할당받은 총 메모리 크기(Byte 단위)
  • freespace - 아직 사용하지 않은 메모리 총량

MemoryContextData

/*
 * MemoryContext
 *      메모리 할당이 진행되는 논리적인 컨텍스트.
 *
 * MemoryContext는 추상적인 타입이고 여러 구현체를 가진다.
 * MemoryContextMethods에는 특정 컨텍스트가 가 함수들에 대한 포인터가 정의되어 있다.
 * C++식으로 표현하자면 MemoryContextMethods는 MemoryContext의 가상 함수 테이블이다.
 *
 * memory context의 실제 구현체인 node type는 반드시 MmeoryContextData와 동일한 필드로 시작해야 한다.
 * 그래야 MemoryContextData 포인터 타입으로 공통된 필드에 접근이 가능하기 때문이다.
 *
 * 참고: typedef MemoryContext는 구조체가 아니라 해당 구조체를 가리키는 포인터 타입이다.
 */

typedef void (*MemoryStatsPrintFunc) (MemoryContext context, void *passthru,
                                      const char *stats_string,
                                      bool print_to_stderr);

typedef struct MemoryContextMethods
{
    /*
     * 주어진 context에서 size만큼의 메모리를 할당하는 함수. 이 함수는 반드시 
     * MCXT_ALLOC_HUGE와 MCXT_ALLOC_NO_OOM 플래그를 처리할 수 있어야 한다.
     * MCXT_ALLOC_ZERO 플래그는 이 함수를 호출하는 함수(calling function)가
     * 처리한다.
     */
    void       *(*alloc) (MemoryContext context, Size size, int flags);

    /* free가 이미 정의된 경우 이 함수를 호출한다. */
    void        (*free_p) (void *pointer);

    /*
     * 이미 할당한 메모리에 대한 크기 변경 요청을 처리하는 함수.
     * 구현체는 반드시 MCXT_ALLOC_HUGE와 MCXT_ALLOC_NO_OOM을 처리할 수 있어야 한다.
     * MCXT_ALLOC_ZERO는 호출자(calling function)에 의해 처리된다.
     */
    void       *(*realloc) (void *pointer, Size size, int flags);

    /*
     * 주어진 memory context에서 할당한 모든 메모리를 무효화(invalidation)하고
     * 해당 컨텍스트가 새로 할당을 시작할 수 있도록 준비한다.
     * 구현체는 이 때 OS에게 초과(excess)) 메모리를 반환할 수 있다. 이 작업은 선택적(optional)이다.
     */
    void        (*reset) (MemoryContext context);

    /* 주어진 MemoryContext에서 할당한 모든 메모리를 해제한다. */
    void        (*delete_context) (MemoryContext context);

    /* pointer가 속한 MemoryContext를 반환한다. */
    MemoryContext (*get_chunk_context) (void *pointer);

    /*
     * pointer가 memory context 내에서 실제로 차지하고 있는 공간의 크기를 반환한다.
     * 메모리 정렬, chunk header에 의한 overhead를 포함한 값을 반환한다.
     */
    Size        (*get_chunk_space) (void *pointer);

    /*
     * 최초 생성 또는 마지막 reset 이후 context에서 한 번도 메모리 할당이 
     * 발생하지 않은 경우 true를 반환한다.
     */
    bool        (*is_empty) (MemoryContext context);
    void        (*stats) (MemoryContext context,
                          MemoryStatsPrintFunc printfunc, void *passthru,
                          MemoryContextCounters *totals,
                          bool print_to_stderr);
#ifdef MEMORY_CONTEXT_CHECKING

    /*
     * context에 대한 유효성 검사를 진행하고 이상한 점이 발견될 경우 
     * WARNING으로 보고한다.
     */
    void        (*check) (MemoryContext context);
#endif
} MemoryContextMethods;

typedef struct MemoryContextData
{
    pg_node_attr(abstract)      /* 이 타입의 인스턴스는 존재할 수 없도록 보장하는 perl 의 함수이다. */

    NodeTag     type;           /* 인스턴스(memory context)의 실제 타입 */
    /* 아래의 두 필드는 alignment wastage를 최소화하기 위해 여기에 위치 */
    bool        isReset;        /* 마지막 reset 이후 메모리 할당한적 없으면 true */
    bool        allowInCritSection; /* critical section에서 palloc이 가능한 경우 true */
    Size        mem_allocated;  /* 이 컨텍스트에서 할당된 메모리를 추적 */
    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 */
    const char *ident;          /* context ID if any */
    MemoryContextCallback *reset_cbs;   /* list of reset/delete callbacks */
} MemoryContextData;

/* utils/palloc.h contains typedef struct MemoryContextData *MemoryContext */

references