summaryrefslogtreecommitdiff
path: root/rts/Stats.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2011-04-14 08:59:39 +0100
committerSimon Marlow <marlowsd@gmail.com>2011-04-14 09:01:52 +0100
commitcc2ea98ac4a15e40a15e89de9e47f33e191ba393 (patch)
treef3ed770c0908c21b13d9f86afb326d5e01e3d28c /rts/Stats.c
parent25297a13bd6be722a74ee87237498a5626b298ef (diff)
downloadhaskell-cc2ea98ac4a15e40a15e89de9e47f33e191ba393.tar.gz
Avoid accumulating slop in the pinned_object_block.
The pinned_object_block is where we allocate small pinned ByteArray# objects. At a GC the pinned_object_block was being treated like other large objects and promoted to the next step/generation, even if it was only partly full. Under some ByteString-heavy workloads this would accumulate on average 2k of slop per GC, and this memory is never released until the ByteArray# objects in the block are freed. So now, we keep allocating into the pinned_object_block until it is completely full, at which point it is handed over to the GC as before. The pinned_object_block might therefore contain objects which a large range of ages, but I don't think this is any worse than the situation before. We still have the fragmentation issue in general, but the new scheme can improve the memory overhead for some workloads dramatically.
Diffstat (limited to 'rts/Stats.c')
-rw-r--r--rts/Stats.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/rts/Stats.c b/rts/Stats.c
index 159a909fce..3e7b5d822f 100644
--- a/rts/Stats.c
+++ b/rts/Stats.c
@@ -798,6 +798,15 @@ statDescribeGens(void)
mut = 0;
for (i = 0; i < n_capabilities; i++) {
mut += countOccupied(capabilities[i].mut_lists[g]);
+
+ // Add the pinned object block.
+ bd = capabilities[i].pinned_object_block;
+ if (bd != NULL) {
+ gen_live += bd->free - bd->start;
+ gen_blocks += bd->blocks;
+ }
+
+ gen_live += gcThreadLiveWords(i,g);
gen_live += gcThreadLiveWords(i,g);
gen_blocks += gcThreadLiveBlocks(i,g);
}