设为首页 加入收藏

TOP

PostgreSQL启动过程中的那些事一:初始化TopMemoryContext和ErrorContext(二)
2014-11-23 20:12:01 来源: 作者: 【 】 浏览:66
Tags:PostgreSQL 启动 过程 那些 初始 TopMemoryContext ErrorContext
ryContext类型的局部变量node,分配内存并初始化。注意,这时还没有初始化TopMemoryContext,所以node的内存空间是malloc出来的。MemoryContext类型的局部变量node初始化完后返回。

MemoryContext

MemoryContextCreate(NodeTag tag, Size size,

MemoryContextMethods*methods,

MemoryContextparent,

const char *name)

{

MemoryContext node;

Size needed = size + strlen(name) + 1;

if(TopMemoryContext == NULL)

{

/*Special case for startup: use good ol' malloc */

node = (MemoryContext)malloc(needed);

Assert(node != NULL);

}

/*Initialize the node as best we can */

MemSet(node, 0, size);

node->type = tag;

node->methods = methods;

node->parent = NULL; /* for themoment */

node->firstchild = NULL;

node->nextchild = NULL;

node->name = ((char *) node) + size;

strcpy(node->name, name);

/*Return to type-specific creation routine to finish up */

return node;

}

AllocSetContextCreate()函数得到从MemoryContextCreate()函数返回的MemoryContextCreate类型的值后转换为AllocSet类型,赋给context,把context其他属性初始化。最后又把context的类型由AllocSet转换为MemoryContext后返回给调用方法,赋值给TopMemoryContext。至此TopMemoryContext初始化完成。

代码见下面。

MemoryContext

AllocSetContextCreate(MemoryContext parent,

constchar *name,

Size minContextSize,

Size initBlockSize,

Size maxBlockSize)

{

AllocSet context;

/* Dothe type-independent part of context creation */

context = (AllocSet) MemoryContextCreate(T_AllocSetContext,

sizeof(AllocSetContext),

&AllocSetMethods,

parent,

name);

context->initBlockSize =initBlockSize;

context->maxBlockSize =maxBlockSize;

context->nextBlockSize =initBlockSize;

context->isReset = true;

return(MemoryContext) context;

}

在初始化TomMemoryContext的过程中,先按AllocSet的类型初始化一个MemoryContext类型的变量,然后把这个变量转成AllocSet类型,初始化AllocSet类型的其它成员,再将其转成MemoryContext类型的变量后赋值给TopMemoryContext。为什么能做这两次类型转换呢?见下面分解。

下面上个图看看初始化出来的TopMemoryContext的结构图(以后所有内存结构图都是低地址在下面,高地址在上面,再后面有内存结构图时就不标低地址位了):

\

TopMemoryContext的内存结构图

\

TopMemoryContext转成AllocSet类型后的内存结构图

上图中分两块说,先看左边的大方块。其中下面深蓝色部分是MemoryContextData的内存结构,深蓝色和上面的浅颜色部分合起来是AllocSetContext的内存结构。

初始化TopMemoryContext的时候,分配的内存大小不是按MemoryContextData结构的大小分的,是按AllocSetContext的大小分的内存,又在紧挨着上面分配了17个字节记录这个MemoryContextData /AllocSetContext 的名字“TopMemoryContext”。

能在初始化TopMemoryContext的过程中能在类型MemoryContextData 、AllocSetContext之间相互转化,是利用了AllocSetContext结构布局上的特点,刚一开始就是个MemoryContextData,接着是其它成员,这样要是把TopMemoryContext当MemoryContextData类型处理,就是上面那个图,图中黑色部分相当于未知,不用管它,剩下的就是MemoryContextData类型,当TopMemoryContext是AllocSetContext类型时,就面的图,它就是个AllocSetContext类型的变量了。这样做的好处是在一个结构里既能管理内存空间,又能管理内存空间里的内容,而且逻辑功能划分很清晰。

哦,有人说从中看出了面向对象编程中继承的影子,嗯、啊,是有点,如果MemoryContextData是父类,AllocSetContext是MemoryContextData的子类,看起来是挺像的,从内存布局上看子类里也少了指向vitualtable 的member function /viturl member function pointer(vptr)。看来从面向对象编程到面向过程编程是技术的渐进,就像设备的升级改造。扯的有点远了,打住。

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Redis在linux上的安装过程和遇到.. 下一篇分页存储过程实例剖析心得

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: