中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

電商網(wǎng)站設(shè)計周志如何寫軟文賺錢

電商網(wǎng)站設(shè)計周志,如何寫軟文賺錢,企業(yè)網(wǎng)站改自適應(yīng),跨境電商七大騙局shopee一、簡介 postgresql大部分的內(nèi)存分配管理都是通過MemoryContext進行操作的, 多個相關(guān)的MemoryContext構(gòu)成了一個樹型結(jié)構(gòu), 多個樹構(gòu)成了一個森林。 實現(xiàn)了三種MemoryContext: SlabContextGenerationContextAllocSetContext 使用全局變量CurrentMemo…

一、簡介

postgresql大部分的內(nèi)存分配管理都是通過MemoryContext進行操作的,
多個相關(guān)的MemoryContext構(gòu)成了一個樹型結(jié)構(gòu),
多個樹構(gòu)成了一個森林。

實現(xiàn)了三種MemoryContext:

  • SlabContext
  • GenerationContext
  • AllocSetContext

使用全局變量CurrentMemoryContext進行MemoryContext切換

二、編程范式

2.1 創(chuàng)建MemoryContext

newcontext = AllocSetContextCreate((MemoryContext) NULL,"TestMemoryContext",ALLOCSET_DEFAULT_SIZES);

2.2 切換需要使用的MemoryContext

MemoryContextSwitchTo(newcontext);

2.3 使用相應(yīng)API進行分配/釋放空間

//分配空間
item = (text *) palloc(VARHDRSZ + len + 1);
//分配空間,并且清空
plabel = palloc0(sizeof(pending_label));
//擴容/縮容
es->steps = repalloc(es->steps, sizeof(ExprEvalStep) * es->steps_alloc);
//釋放空間
pfree(r);

2.4 重置MemoryContext

MemoryContextReset(argContext);

2.5 銷毀MemoryContext

MemoryContextDelete(tmpCxt);

三、實現(xiàn)原理

3.1 數(shù)據(jù)結(jié)構(gòu)簡介

AllocSetContext由三部分構(gòu)成, MemoryContextData + AllocBlock + AllocChunk
MemoryContextData:

  • 由如下字段將各個MemoryContext構(gòu)成樹型結(jié)構(gòu)
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 */
  • 虛函數(shù)表,實現(xiàn)統(tǒng)一接口,不同實現(xiàn)
const MemoryContextMethods *methods;	/* virtual function table */

AllocBlock:

  • 由如下字段將block構(gòu)成一個雙向鏈表
AllocBlock	prev;			/* prev block in aset's blocks list, if any */
AllocBlock	next;			/* next block in aset's blocks list, if any */
  • 標(biāo)識可用空間范圍
char	   *freeptr;		/* start of free space in this block */
char	   *endptr;			/* end of space in this block */

AllocChunk:

  • chunk中可用大小
Size		size;

3.2 初始化

#define AllocSetContextCreate \AllocSetContextCreateInternal#define ALLOCSET_DEFAULT_MINSIZE   0
#define ALLOCSET_DEFAULT_INITSIZE  (8 * 1024)
#define ALLOCSET_DEFAULT_MAXSIZE   (8 * 1024 * 1024)
#define ALLOCSET_DEFAULT_SIZES \ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZETopMemoryContext = AllocSetContextCreate((MemoryContext) NULL,"TopMemoryContext",ALLOCSET_DEFAULT_SIZES);
MemoryContext
AllocSetContextCreateInternal(MemoryContext parent,const char *name,Size minContextSize,Size initBlockSize,Size maxBlockSize)
{int			freeListIndex;Size		firstBlockSize;AllocSet	set;AllocBlock	block;
.../* Determine size of initial block */firstBlockSize = MAXALIGN(sizeof(AllocSetContext)) +ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;if (minContextSize != 0)firstBlockSize = Max(firstBlockSize, minContextSize);elsefirstBlockSize = Max(firstBlockSize, initBlockSize);/** Allocate the initial block.  Unlike other aset.c blocks, it starts with* the context header and its block header follows that.*/set = (AllocSet) malloc(firstBlockSize);.../* Fill in the initial block's block header */block = (AllocBlock) (((char *) set) + MAXALIGN(sizeof(AllocSetContext)));block->aset = set;block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;block->endptr = ((char *) set) + firstBlockSize;block->prev = NULL;block->next = NULL;
.../* Remember block as part of block list */set->blocks = block;/* Mark block as not to be released at reset time */set->keeper = block;...set->initBlockSize = initBlockSize;set->maxBlockSize = maxBlockSize;set->nextBlockSize = initBlockSize;set->freeListIndex = freeListIndex;
...set->allocChunkLimit = ALLOC_CHUNK_LIMIT;while ((Size) (set->allocChunkLimit + ALLOC_CHUNKHDRSZ) >(Size) ((maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION))set->allocChunkLimit >>= 1;/* Finally, do the type-independent part of context creation */MemoryContextCreate((MemoryContext) set,T_AllocSetContext,&AllocSetMethods,parent,name);((MemoryContext) set)->mem_allocated = firstBlockSize;return (MemoryContext) set;
}

在這里插入圖片描述

3.3 分配空間

void *
palloc(Size size)
{/* duplicates MemoryContextAlloc to avoid increased overhead */void	   *ret;MemoryContext context = CurrentMemoryContext;
...context->isReset = false;ret = context->methods->alloc(context, size);
...return ret;
}

3.3.1 分配空間大于allocChunkLimit

static void *
AllocSetAlloc(MemoryContext context, Size size)
{AllocSet	set = (AllocSet) context;AllocBlock	block;AllocChunk	chunk;int			fidx;Size		chunk_size;Size		blksize;.../** If requested size exceeds maximum for chunks, allocate an entire block* for this request.*/if (size > set->allocChunkLimit){chunk_size = MAXALIGN(size);blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;block = (AllocBlock) malloc(blksize);if (block == NULL)return NULL;context->mem_allocated += blksize;block->aset = set;block->freeptr = block->endptr = ((char *) block) + blksize;chunk = (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ);chunk->aset = set;chunk->size = chunk_size;/** Stick the new block underneath the active allocation block, if any,* so that we don't lose the use of the space remaining therein.*/if (set->blocks != NULL){block->prev = set->blocks;block->next = set->blocks->next;if (block->next)block->next->prev = block;set->blocks->next = block;}else{block->prev = NULL;block->next = NULL;set->blocks = block;}return AllocChunkGetPointer(chunk);}
...
}

例如分配16K

char *ptr = palloc(16 * 1024);

在這里插入圖片描述

例如分配32K

char *ptr = palloc(32 * 1024);

在這里插入圖片描述

3.3.2 分配空間小于等于allocChunkLimit

#define ALLOC_MINBITS		3	/* smallest chunk size is 8 bytes */static inline int
AllocSetFreeIndex(Size size)
{int			idx;if (size > (1 << ALLOC_MINBITS)){
...idx = 31 - __builtin_clz((uint32) size - 1) - ALLOC_MINBITS + 1;
...}elseidx = 0;return idx;
}
fidx = AllocSetFreeIndex(size);/** Choose the actual chunk size to allocate.*/
chunk_size = (1 << ALLOC_MINBITS) << fidx;
  • 分配小于等于8字節(jié)
    小于等于8的,最終將分配8字節(jié)

  • 分配大于8字節(jié)
    通過__builtin_clz計算size-1的前導(dǎo)0的個數(shù),然后通過減法計算size的對其位數(shù)(非常高效的方式

3.3.2.1 當(dāng)前block有足夠空間

if ((block = set->blocks) != NULL)
{
...
}
/** OK, do the allocation*/chunk = (AllocChunk) (block->freeptr);
...block->freeptr += (chunk_size + ALLOC_CHUNKHDRSZ);
...chunk->aset = (void *) set;chunk->size = chunk_size;
...return AllocChunkGetPointer(chunk);

例如分配20byte

char *ptr = palloc(20);

通過對其,實際分配32byte

在這里插入圖片描述

3.3.2.2 當(dāng)前block沒有足夠的空間

隨著分配,當(dāng)前block中的可用空間越來越小,再次分配時,將不夠當(dāng)前分配

Size availspace = block->endptr - block->freeptr;
if (availspace < (chunk_size + ALLOC_CHUNKHDRSZ))
{
...
}

在這里插入圖片描述

3.3.2.2.1 當(dāng)前block還有一些空間
if (availspace < (chunk_size + ALLOC_CHUNKHDRSZ)){while (availspace >= ((1 << ALLOC_MINBITS) + ALLOC_CHUNKHDRSZ)){Size		availchunk = availspace - ALLOC_CHUNKHDRSZ;int			a_fidx = AllocSetFreeIndex(availchunk);...if (availchunk != ((Size) 1 << (a_fidx + ALLOC_MINBITS))){a_fidx--;Assert(a_fidx >= 0);availchunk = ((Size) 1 << (a_fidx + ALLOC_MINBITS));}chunk = (AllocChunk) (block->freeptr);
...block->freeptr += (availchunk + ALLOC_CHUNKHDRSZ);availspace -= (availchunk + ALLOC_CHUNKHDRSZ);chunk->size = availchunk;chunk->aset = (void *) set->freelist[a_fidx];set->freelist[a_fidx] = chunk;}/* Mark that we need to create a new block */block = NULL;}

將剩余空間大小,按照對其的大小放到freelist中,構(gòu)成一個單鏈表,用于后續(xù)分配時,直接從這里獲取。
可能會有一小塊用不了的空間
在這里插入圖片描述

3.3.2.2.2 創(chuàng)建新block
  • 第一次創(chuàng)建時,使用initBlockSize
  • 后續(xù)將會是上次block的兩倍,當(dāng)大于maxBlockSize,使用maxBlockSize
  • 如果新block大小依然小于需要分配的空間,則繼續(xù)擴大
/** Time to create a new regular (multi-chunk) block?*/if (block == NULL){Size		required_size;/** The first such block has size initBlockSize, and we double the* space in each succeeding block, but not more than maxBlockSize.*/blksize = set->nextBlockSize;set->nextBlockSize <<= 1;if (set->nextBlockSize > set->maxBlockSize)set->nextBlockSize = set->maxBlockSize;/** If initBlockSize is less than ALLOC_CHUNK_LIMIT, we could need more* space... but try to keep it a power of 2.*/required_size = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;while (blksize < required_size)blksize <<= 1;/* Try to allocate it */block = (AllocBlock) malloc(blksize);
...if (block == NULL)return NULL;context->mem_allocated += blksize;block->aset = set;block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;block->endptr = ((char *) block) + blksize;/* Mark unallocated space NOACCESS. */VALGRIND_MAKE_MEM_NOACCESS(block->freeptr,blksize - ALLOC_BLOCKHDRSZ);block->prev = NULL;block->next = set->blocks;if (block->next)block->next->prev = block;set->blocks = block;}

在這里插入圖片描述

在這里插入圖片描述

3.3.3 從freelist中分配

fidx = AllocSetFreeIndex(size);
chunk = set->freelist[fidx];
if (chunk != NULL)
{set->freelist[fidx] = (AllocChunk) chunk->aset;chunk->aset = (void *) set;
...return AllocChunkGetPointer(chunk);
}

在這里插入圖片描述

3.4 釋放空間

void
pfree(void *pointer)
{MemoryContext context = GetMemoryChunkContext(pointer);context->methods->free_p(context, pointer);
...
}

3.4.1 直接釋放

static void
AllocSetFree(MemoryContext context, void *pointer)
{AllocSet	set = (AllocSet) context;AllocChunk	chunk = AllocPointerGetChunk(pointer);
...if (chunk->size > set->allocChunkLimit){AllocBlock	block = (AllocBlock) (((char *) chunk) - ALLOC_BLOCKHDRSZ);.../* OK, remove block from aset's list and free it */if (block->prev)block->prev->next = block->next;elseset->blocks = block->next;if (block->next)block->next->prev = block->prev;context->mem_allocated -= block->endptr - ((char *) block);
...free(block);}else{...}
}

見 3.3.1, 大于chunklimit的直接malloc的空間,而不是從block中分配的,因此直接釋放,并且將此block從雙向鏈表中刪除。
在這里插入圖片描述

3.4.2 加入freelist中

static void
AllocSetFree(MemoryContext context, void *pointer)
{AllocSet	set = (AllocSet) context;AllocChunk	chunk = AllocPointerGetChunk(pointer);/* Allow access to private part of chunk header. */VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOCCHUNK_PRIVATE_LEN);#ifdef MEMORY_CONTEXT_CHECKING/* Test for someone scribbling on unused space in chunk */if (chunk->requested_size < chunk->size)if (!sentinel_ok(pointer, chunk->requested_size))elog(WARNING, "detected write past chunk end in %s %p",set->header.name, chunk);
#endifif (chunk->size > set->allocChunkLimit){...}else{/* Normal case, put the chunk into appropriate freelist */int			fidx = AllocSetFreeIndex(chunk->size);chunk->aset = (void *) set->freelist[fidx];
...set->freelist[fidx] = chunk;}
}

在這里插入圖片描述

http://www.risenshineclean.com/news/9644.html

相關(guān)文章:

  • 網(wǎng)站上面的內(nèi)容里面放照片怎么做的網(wǎng)絡(luò)域名怎么查
  • 做網(wǎng)站建設(shè)百度網(wǎng)站的域名地址
  • 怎么對網(wǎng)站做壓力測試seo排名優(yōu)化價格
  • wordpress靜態(tài)ip上海優(yōu)化外包
  • 合肥政務(wù)新區(qū)建設(shè)局網(wǎng)站百度搜索引擎的功能
  • 莆田有哪幾家做網(wǎng)站設(shè)計的全球網(wǎng)站排名前100
  • 建筑工程有限責(zé)任公司搜索引擎優(yōu)化教程
  • 公司網(wǎng)站的建站要點seo還有前景嗎
  • 西安網(wǎng)站設(shè)計品牌詞優(yōu)化
  • 華碩路由器做網(wǎng)站什么軟件可以發(fā)帖子做推廣
  • 做電商有哪些網(wǎng)站推廣平臺收費標(biāo)準(zhǔn)
  • 上海網(wǎng)站改版服務(wù)百度葷seo公司
  • 小米手機做網(wǎng)站服務(wù)器嗎網(wǎng)站排名優(yōu)化公司
  • 哈爾濱快速建站案例百度識圖網(wǎng)頁版入口
  • 彩票網(wǎng)站怎么做的營銷模式
  • 凡科做網(wǎng)站不要錢seo搜索引擎入門教程
  • 做報名網(wǎng)站中國國家培訓(xùn)網(wǎng)是真的嗎
  • spd2007怎么創(chuàng)建網(wǎng)站品牌推廣的意義
  • 網(wǎng)站開發(fā)代理報價表成都私人網(wǎng)站制作
  • 北京做網(wǎng)站在線html5制作網(wǎng)站
  • 泰安人力資源招聘長沙靠譜關(guān)鍵詞優(yōu)化服務(wù)
  • 獨立設(shè)計購物網(wǎng)站網(wǎng)絡(luò)推廣方案范例
  • 網(wǎng)站seo優(yōu)化關(guān)鍵詞國內(nèi)外搜索引擎大全
  • 學(xué)校網(wǎng)站設(shè)計的作用營銷平臺建設(shè)
  • wordpress限制站點使用時間河南品牌網(wǎng)站建設(shè)
  • 最基本的網(wǎng)絡(luò)營銷站點西安優(yōu)化網(wǎng)站公司
  • wordpress做的好的網(wǎng)站如何優(yōu)化網(wǎng)站快速排名
  • 萊山做網(wǎng)站的公司熊貓關(guān)鍵詞工具官網(wǎng)
  • 域名注冊后怎么建網(wǎng)站全網(wǎng)營銷推廣案例
  • 商城網(wǎng)站都有什么功能模塊免費網(wǎng)站推廣工具