From e59678ecf9380ba1d26ee3f124c04f1ebd2b6ea4 Mon Sep 17 00:00:00 2001 From: Richard Brooksby Date: Tue, 11 Feb 2014 18:26:00 +0000 Subject: [PATCH] =?UTF-8?q?Purging=20half=20of=20the=20spare=20memory,=20r?= =?UTF-8?q?ather=20than=20just=20enough=20to=20get=20under=20the=20limit,?= =?UTF-8?q?=20so=20that=20there=20aren=E2=80=99t=20many=20small=20unmaps,?= =?UTF-8?q?=20and=20many=20scans=20for=20spare=20pages.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copied from Perforce Change: 184326 ServerID: perforce.ravenbrook.com --- mps/code/arenavm.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index b4a4e6e2b60..b8f814d8e3c 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -1296,6 +1296,8 @@ static void tablePagesUnmap(VMChunk vmChunk, Index basePage, Index limitPage) /* Lower basePage until we reach a desciptor we can't unmap, or the beginning of the table. */ + /* FIXME: Are the descriptors below chunk->allocBase initialised? Shouldn't + we stop there? pageTable[allocBase] might cross a page boundary. */ AVER(pageState(vmChunk, basePage) == PageStateFREE); while (basePage > 0) { Bool mapped = pageDescIsMapped(vmChunk, basePage - 1); @@ -1714,8 +1716,15 @@ static void VMFree(Addr base, Size size, Pool pool) /* Consider returning memory to the OS. */ /* TODO: Chunks are only destroyed when ArenaCompact is called, and that is only called from TraceReclaim. Should consider destroying chunks here. */ - if (arena->spareCommitted > arena->spareCommitLimit) - (void)VMPurgeSpare(arena, arena->spareCommitted - arena->spareCommitLimit); + if (arena->spareCommitted > arena->spareCommitLimit) { + /* Purge half of the spare memory, not just the extra sliver, so + that we return a reasonable amount of memory in one go, and avoid + lots of small unmappings, each of which has an overhead. */ + /* TODO: Consider making this time-based. */ + /* TODO: Consider making this smarter about the overheads tradeoff. */ + Size toPurge = arena->spareCommitted - arena->spareCommitLimit / 2; + (void)VMPurgeSpare(arena, toPurge); + } }