Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite00912e

Browse files
committed
Specialize MemoryContextMemAllocated().
An AllocSet doubles the size of allocated blocks (up to maxBlockSize),which means that the current block can represent half of the totalallocated space for the memory context. But the free space in thecurrent block may never have been touched, so don't count theuntouched memory as allocated for the purposes ofMemoryContextMemAllocated().Discussion:https://postgr.es/m/ec63d70b668818255486a83ffadc3aec492c1f57.camel@j-davis.com
1 parent487e986 commite00912e

File tree

5 files changed

+77
-28
lines changed

5 files changed

+77
-28
lines changed

‎src/backend/utils/mmgr/aset.c

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ typedef struct AllocSetContext
132132
SizemaxBlockSize;/* maximum block size */
133133
SizenextBlockSize;/* next block size to allocate */
134134
SizeallocChunkLimit;/* effective chunk size limit */
135+
SizememAllocated;/* track memory allocated for this context */
135136
AllocBlockkeeper;/* keep this block over resets */
136137
/* freelist this context could be put in, or -1 if not a candidate: */
137138
intfreeListIndex;/* index in context_freelists[], or -1 */
@@ -272,6 +273,7 @@ static void *AllocSetRealloc(MemoryContext context, void *pointer, Size size);
272273
staticvoidAllocSetReset(MemoryContextcontext);
273274
staticvoidAllocSetDelete(MemoryContextcontext);
274275
staticSizeAllocSetGetChunkSpace(MemoryContextcontext,void*pointer);
276+
staticSizeAllocSetMemAllocated(MemoryContextcontext);
275277
staticboolAllocSetIsEmpty(MemoryContextcontext);
276278
staticvoidAllocSetStats(MemoryContextcontext,
277279
MemoryStatsPrintFuncprintfunc,void*passthru,
@@ -291,6 +293,7 @@ static const MemoryContextMethods AllocSetMethods = {
291293
AllocSetReset,
292294
AllocSetDelete,
293295
AllocSetGetChunkSpace,
296+
AllocSetMemAllocated,
294297
AllocSetIsEmpty,
295298
AllocSetStats
296299
#ifdefMEMORY_CONTEXT_CHECKING
@@ -464,8 +467,7 @@ AllocSetContextCreateInternal(MemoryContext parent,
464467
parent,
465468
name);
466469

467-
((MemoryContext)set)->mem_allocated=
468-
set->keeper->endptr- ((char*)set);
470+
set->memAllocated=set->keeper->endptr- ((char*)set);
469471

470472
return (MemoryContext)set;
471473
}
@@ -555,7 +557,7 @@ AllocSetContextCreateInternal(MemoryContext parent,
555557
parent,
556558
name);
557559

558-
((MemoryContext)set)->mem_allocated=firstBlockSize;
560+
set->memAllocated=firstBlockSize;
559561

560562
return (MemoryContext)set;
561563
}
@@ -617,7 +619,7 @@ AllocSetReset(MemoryContext context)
617619
else
618620
{
619621
/* Normal case, release the block */
620-
context->mem_allocated-=block->endptr- ((char*)block);
622+
set->memAllocated-=block->endptr- ((char*)block);
621623

622624
#ifdefCLOBBER_FREED_MEMORY
623625
wipe_mem(block,block->freeptr- ((char*)block));
@@ -627,7 +629,7 @@ AllocSetReset(MemoryContext context)
627629
block=next;
628630
}
629631

630-
Assert(context->mem_allocated==keepersize);
632+
Assert(set->memAllocated==keepersize);
631633

632634
/* Reset block size allocation sequence, too */
633635
set->nextBlockSize=set->initBlockSize;
@@ -703,7 +705,7 @@ AllocSetDelete(MemoryContext context)
703705
AllocBlocknext=block->next;
704706

705707
if (block!=set->keeper)
706-
context->mem_allocated-=block->endptr- ((char*)block);
708+
set->memAllocated-=block->endptr- ((char*)block);
707709

708710
#ifdefCLOBBER_FREED_MEMORY
709711
wipe_mem(block,block->freeptr- ((char*)block));
@@ -715,7 +717,7 @@ AllocSetDelete(MemoryContext context)
715717
block=next;
716718
}
717719

718-
Assert(context->mem_allocated==keepersize);
720+
Assert(set->memAllocated==keepersize);
719721

720722
/* Finally, free the context header, including the keeper block */
721723
free(set);
@@ -758,7 +760,7 @@ AllocSetAlloc(MemoryContext context, Size size)
758760
if (block==NULL)
759761
returnNULL;
760762

761-
context->mem_allocated+=blksize;
763+
set->memAllocated+=blksize;
762764

763765
block->aset=set;
764766
block->freeptr=block->endptr= ((char*)block)+blksize;
@@ -955,7 +957,7 @@ AllocSetAlloc(MemoryContext context, Size size)
955957
if (block==NULL)
956958
returnNULL;
957959

958-
context->mem_allocated+=blksize;
960+
set->memAllocated+=blksize;
959961

960962
block->aset=set;
961963
block->freeptr= ((char*)block)+ALLOC_BLOCKHDRSZ;
@@ -1058,7 +1060,7 @@ AllocSetFree(MemoryContext context, void *pointer)
10581060
if (block->next)
10591061
block->next->prev=block->prev;
10601062

1061-
context->mem_allocated-=block->endptr- ((char*)block);
1063+
set->memAllocated-=block->endptr- ((char*)block);
10621064

10631065
#ifdefCLOBBER_FREED_MEMORY
10641066
wipe_mem(block,block->freeptr- ((char*)block));
@@ -1161,8 +1163,8 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
11611163
}
11621164

11631165
/* updated separately, not to underflow when (oldblksize > blksize) */
1164-
context->mem_allocated-=oldblksize;
1165-
context->mem_allocated+=blksize;
1166+
set->memAllocated-=oldblksize;
1167+
set->memAllocated+=blksize;
11661168

11671169
block->freeptr=block->endptr= ((char*)block)+blksize;
11681170

@@ -1337,6 +1339,24 @@ AllocSetGetChunkSpace(MemoryContext context, void *pointer)
13371339
returnresult;
13381340
}
13391341

1342+
/*
1343+
* All memory currently allocated for this context (including fragmentation
1344+
* and freed chunks).
1345+
*
1346+
* Allocation sizes double (up to maxBlockSize), so the current block may
1347+
* represent half of the total space allocated to the context. Subtract away
1348+
* the free space at the tail of the current block, which may never have been
1349+
* touched.
1350+
*/
1351+
staticSize
1352+
AllocSetMemAllocated(MemoryContextcontext)
1353+
{
1354+
AllocSetset= (AllocSet)context;
1355+
AllocBlockcurrentBlock=set->blocks;
1356+
SizetailSpace=currentBlock->endptr-currentBlock->freeptr;
1357+
returnset->memAllocated-tailSpace;
1358+
}
1359+
13401360
/*
13411361
* AllocSetIsEmpty
13421362
*Is an allocset empty of any allocated space?
@@ -1538,7 +1558,7 @@ AllocSetCheck(MemoryContext context)
15381558
name,block);
15391559
}
15401560

1541-
Assert(total_allocated==context->mem_allocated);
1561+
Assert(total_allocated==set->memAllocated);
15421562
}
15431563

15441564
#endif/* MEMORY_CONTEXT_CHECKING */

‎src/backend/utils/mmgr/generation.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ typedef struct GenerationContext
6161

6262
/* Generational context parameters */
6363
SizeblockSize;/* standard block size */
64+
SizememAllocated;/* track memory allocated for this context */
6465

6566
GenerationBlock*block;/* current (most recently allocated) block */
6667
dlist_headblocks;/* list of blocks */
@@ -152,6 +153,7 @@ static void *GenerationRealloc(MemoryContext context, void *pointer, Size size);
152153
staticvoidGenerationReset(MemoryContextcontext);
153154
staticvoidGenerationDelete(MemoryContextcontext);
154155
staticSizeGenerationGetChunkSpace(MemoryContextcontext,void*pointer);
156+
staticSizeGenerationMemAllocated(MemoryContextcontext);
155157
staticboolGenerationIsEmpty(MemoryContextcontext);
156158
staticvoidGenerationStats(MemoryContextcontext,
157159
MemoryStatsPrintFuncprintfunc,void*passthru,
@@ -171,6 +173,7 @@ static const MemoryContextMethods GenerationMethods = {
171173
GenerationReset,
172174
GenerationDelete,
173175
GenerationGetChunkSpace,
176+
GenerationMemAllocated,
174177
GenerationIsEmpty,
175178
GenerationStats
176179
#ifdefMEMORY_CONTEXT_CHECKING
@@ -258,6 +261,7 @@ GenerationContextCreate(MemoryContext parent,
258261

259262
/* Fill in GenerationContext-specific header fields */
260263
set->blockSize=blockSize;
264+
set->memAllocated=0;
261265
set->block=NULL;
262266
dlist_init(&set->blocks);
263267

@@ -297,7 +301,7 @@ GenerationReset(MemoryContext context)
297301

298302
dlist_delete(miter.cur);
299303

300-
context->mem_allocated-=block->blksize;
304+
set->memAllocated-=block->blksize;
301305

302306
#ifdefCLOBBER_FREED_MEMORY
303307
wipe_mem(block,block->blksize);
@@ -354,7 +358,7 @@ GenerationAlloc(MemoryContext context, Size size)
354358
if (block==NULL)
355359
returnNULL;
356360

357-
context->mem_allocated+=blksize;
361+
set->memAllocated+=blksize;
358362

359363
/* block with a single (used) chunk */
360364
block->blksize=blksize;
@@ -411,7 +415,7 @@ GenerationAlloc(MemoryContext context, Size size)
411415
if (block==NULL)
412416
returnNULL;
413417

414-
context->mem_allocated+=blksize;
418+
set->memAllocated+=blksize;
415419

416420
block->blksize=blksize;
417421
block->nchunks=0;
@@ -528,7 +532,7 @@ GenerationFree(MemoryContext context, void *pointer)
528532
if (set->block==block)
529533
set->block=NULL;
530534

531-
context->mem_allocated-=block->blksize;
535+
set->memAllocated-=block->blksize;
532536
free(block);
533537
}
534538

@@ -666,6 +670,17 @@ GenerationGetChunkSpace(MemoryContext context, void *pointer)
666670
returnresult;
667671
}
668672

673+
/*
674+
* All memory currently allocated for this context (including fragmentation
675+
* and freed chunks).
676+
*/
677+
staticSize
678+
GenerationMemAllocated(MemoryContextcontext)
679+
{
680+
GenerationContext*set= (GenerationContext*)context;
681+
returnset->memAllocated;
682+
}
683+
669684
/*
670685
* GenerationIsEmpty
671686
*Is a GenerationContext empty of any allocated space?
@@ -844,7 +859,7 @@ GenerationCheck(MemoryContext context)
844859
name,nfree,block,block->nfree);
845860
}
846861

847-
Assert(total_allocated==context->mem_allocated);
862+
Assert(total_allocated==gen->memAllocated);
848863
}
849864

850865
#endif/* MEMORY_CONTEXT_CHECKING */

‎src/backend/utils/mmgr/mcxt.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ MemoryContextIsEmpty(MemoryContext context)
469469
Size
470470
MemoryContextMemAllocated(MemoryContextcontext,boolrecurse)
471471
{
472-
Sizetotal=context->mem_allocated;
472+
Sizetotal=context->methods->mem_allocated(context);
473473

474474
AssertArg(MemoryContextIsValid(context));
475475

@@ -760,7 +760,6 @@ MemoryContextCreate(MemoryContext node,
760760
node->methods=methods;
761761
node->parent=parent;
762762
node->firstchild=NULL;
763-
node->mem_allocated=0;
764763
node->prevchild=NULL;
765764
node->name=name;
766765
node->ident=NULL;

‎src/backend/utils/mmgr/slab.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ typedef struct SlabContext
6767
SizefullChunkSize;/* chunk size including header and alignment */
6868
SizeblockSize;/* block size */
6969
SizeheaderSize;/* allocated size of context header */
70+
SizememAllocated;/* track memory allocated for this context */
7071
intchunksPerBlock;/* number of chunks per block */
7172
intminFreeChunks;/* min number of free chunks in any block */
7273
intnblocks;/* number of blocks allocated */
@@ -132,6 +133,7 @@ static void *SlabRealloc(MemoryContext context, void *pointer, Size size);
132133
staticvoidSlabReset(MemoryContextcontext);
133134
staticvoidSlabDelete(MemoryContextcontext);
134135
staticSizeSlabGetChunkSpace(MemoryContextcontext,void*pointer);
136+
staticSizeSlabMemAllocated(MemoryContextcontext);
135137
staticboolSlabIsEmpty(MemoryContextcontext);
136138
staticvoidSlabStats(MemoryContextcontext,
137139
MemoryStatsPrintFuncprintfunc,void*passthru,
@@ -150,6 +152,7 @@ static const MemoryContextMethods SlabMethods = {
150152
SlabReset,
151153
SlabDelete,
152154
SlabGetChunkSpace,
155+
SlabMemAllocated,
153156
SlabIsEmpty,
154157
SlabStats
155158
#ifdefMEMORY_CONTEXT_CHECKING
@@ -262,6 +265,7 @@ SlabContextCreate(MemoryContext parent,
262265
slab->fullChunkSize=fullChunkSize;
263266
slab->blockSize=blockSize;
264267
slab->headerSize=headerSize;
268+
slab->memAllocated=0;
265269
slab->chunksPerBlock=chunksPerBlock;
266270
slab->minFreeChunks=0;
267271
slab->nblocks=0;
@@ -286,6 +290,17 @@ SlabContextCreate(MemoryContext parent,
286290
return (MemoryContext)slab;
287291
}
288292

293+
/*
294+
* All memory currently allocated for this context (including fragmentation
295+
* and freed chunks).
296+
*/
297+
staticSize
298+
SlabMemAllocated(MemoryContextcontext)
299+
{
300+
SlabContext*slab= (SlabContext*)context;
301+
returnslab->memAllocated;
302+
}
303+
289304
/*
290305
* SlabReset
291306
*Frees all memory which is allocated in the given set.
@@ -322,14 +337,14 @@ SlabReset(MemoryContext context)
322337
#endif
323338
free(block);
324339
slab->nblocks--;
325-
context->mem_allocated-=slab->blockSize;
340+
slab->memAllocated-=slab->blockSize;
326341
}
327342
}
328343

329344
slab->minFreeChunks=0;
330345

331346
Assert(slab->nblocks==0);
332-
Assert(context->mem_allocated==0);
347+
Assert(slab->memAllocated==0);
333348
}
334349

335350
/*
@@ -407,7 +422,7 @@ SlabAlloc(MemoryContext context, Size size)
407422

408423
slab->minFreeChunks=slab->chunksPerBlock;
409424
slab->nblocks+=1;
410-
context->mem_allocated+=slab->blockSize;
425+
slab->memAllocated+=slab->blockSize;
411426
}
412427

413428
/* grab the block from the freelist (even the new block is there) */
@@ -501,7 +516,7 @@ SlabAlloc(MemoryContext context, Size size)
501516

502517
SlabAllocInfo(slab,chunk);
503518

504-
Assert(slab->nblocks*slab->blockSize==context->mem_allocated);
519+
Assert(slab->nblocks*slab->blockSize==slab->memAllocated);
505520

506521
returnSlabChunkGetPointer(chunk);
507522
}
@@ -578,13 +593,13 @@ SlabFree(MemoryContext context, void *pointer)
578593
{
579594
free(block);
580595
slab->nblocks--;
581-
context->mem_allocated-=slab->blockSize;
596+
slab->memAllocated-=slab->blockSize;
582597
}
583598
else
584599
dlist_push_head(&slab->freelist[block->nfree],&block->node);
585600

586601
Assert(slab->nblocks >=0);
587-
Assert(slab->nblocks*slab->blockSize==context->mem_allocated);
602+
Assert(slab->nblocks*slab->blockSize==slab->memAllocated);
588603
}
589604

590605
/*
@@ -804,7 +819,7 @@ SlabCheck(MemoryContext context)
804819
}
805820
}
806821

807-
Assert(slab->nblocks*slab->blockSize==context->mem_allocated);
822+
Assert(slab->nblocks*slab->blockSize==slab->memAllocated);
808823
}
809824

810825
#endif/* MEMORY_CONTEXT_CHECKING */

‎src/include/nodes/memnodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ typedef struct MemoryContextMethods
6363
void(*reset) (MemoryContextcontext);
6464
void(*delete_context) (MemoryContextcontext);
6565
Size(*get_chunk_space) (MemoryContextcontext,void*pointer);
66+
Size(*mem_allocated) (MemoryContextcontext);
6667
bool(*is_empty) (MemoryContextcontext);
6768
void(*stats) (MemoryContextcontext,
6869
MemoryStatsPrintFuncprintfunc,void*passthru,
@@ -79,7 +80,6 @@ typedef struct MemoryContextData
7980
/* these two fields are placed here to minimize alignment wastage: */
8081
boolisReset;/* T = no space alloced since last reset */
8182
boolallowInCritSection;/* allow palloc in critical section */
82-
Sizemem_allocated;/* track memory allocated for this context */
8383
constMemoryContextMethods*methods;/* virtual function table */
8484
MemoryContextparent;/* NULL if no parent (toplevel context) */
8585
MemoryContextfirstchild;/* head of linked list of children */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp