summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libraries/base/GHC/Stats.hsc7
-rw-r--r--libraries/base/changelog.md1
-rw-r--r--rts/Stats.c8
-rw-r--r--rts/include/RtsAPI.h2
4 files changed, 15 insertions, 3 deletions
diff --git a/libraries/base/GHC/Stats.hsc b/libraries/base/GHC/Stats.hsc
index 8504e1fff3..08e973b213 100644
--- a/libraries/base/GHC/Stats.hsc
+++ b/libraries/base/GHC/Stats.hsc
@@ -159,6 +159,11 @@ data GCDetails = GCDetails {
, gcdetails_par_max_copied_bytes :: Word64
-- | In parallel GC, the amount of balanced data copied by all threads
, gcdetails_par_balanced_copied_bytes :: Word64
+ -- | The amount of memory lost due to block fragmentation in bytes.
+ -- Block fragmentation is the difference between the amount of blocks retained by the RTS and the blocks that are in use.
+ -- This occurs when megablocks are only sparsely used, eg, when data that cannot be moved retains a megablock.
+ -- @since 4.17.0.0
+ , gcdetails_block_fragmentation_bytes :: Word64
-- | The time elapsed during synchronisation before GC
, gcdetails_sync_elapsed_ns :: RtsTime
-- | The CPU time used during GC itself
@@ -241,6 +246,8 @@ getRTSStats = do
(# peek GCDetails, par_max_copied_bytes) pgc
gcdetails_par_balanced_copied_bytes <-
(# peek GCDetails, par_balanced_copied_bytes) pgc
+ gcdetails_block_fragmentation_bytes <-
+ (# peek GCDetails, block_fragmentation_bytes) pgc
gcdetails_sync_elapsed_ns <- (# peek GCDetails, sync_elapsed_ns) pgc
gcdetails_cpu_ns <- (# peek GCDetails, cpu_ns) pgc
gcdetails_elapsed_ns <- (# peek GCDetails, elapsed_ns) pgc
diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index a11b059000..8888a79727 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -36,6 +36,7 @@
#10](https://github.com/haskell/core-libraries-committee/issues/10) for the
related discussion, as well as [the migration
guide](https://github.com/haskell/core-libraries-committee/blob/main/guides/functor-combinator-instances-and-class1s.md).
+ * Add `gcdetails_block_fragmentation_bytes` to `GHC.Stats.GCDetails` to track heap fragmentation.
## 4.17.0.0 *August 2022*
diff --git a/rts/Stats.c b/rts/Stats.c
index 82a4e5dff5..517e6c32f2 100644
--- a/rts/Stats.c
+++ b/rts/Stats.c
@@ -182,6 +182,7 @@ initStats0(void)
.copied_bytes = 0,
.par_max_copied_bytes = 0,
.par_balanced_copied_bytes = 0,
+ .block_fragmentation_bytes = 0,
.sync_elapsed_ns = 0,
.cpu_ns = 0,
.elapsed_ns = 0,
@@ -482,6 +483,9 @@ stat_endGC (Capability *cap, gc_thread *initiating_gct, W_ live, W_ copied, W_ s
stats.gc.copied_bytes = copied * sizeof(W_);
stats.gc.par_max_copied_bytes = par_max_copied * sizeof(W_);
stats.gc.par_balanced_copied_bytes = par_balanced_copied * sizeof(W_);
+ stats.gc.block_fragmentation_bytes =
+ (mblocks_allocated * BLOCKS_PER_MBLOCK
+ - n_alloc_blocks) * BLOCK_SIZE;
bool stats_enabled =
RtsFlags.GcFlags.giveStats != NO_GC_STATS ||
@@ -582,9 +586,7 @@ stat_endGC (Capability *cap, gc_thread *initiating_gct, W_ live, W_ copied, W_ s
stats.gc.gen,
stats.gc.copied_bytes,
stats.gc.slop_bytes,
- /* current loss due to fragmentation */
- (mblocks_allocated * BLOCKS_PER_MBLOCK
- - n_alloc_blocks) * BLOCK_SIZE,
+ stats.gc.block_fragmentation_bytes,
par_n_threads,
stats.gc.par_max_copied_bytes,
stats.gc.copied_bytes,
diff --git a/rts/include/RtsAPI.h b/rts/include/RtsAPI.h
index 672673498f..08c1b62853 100644
--- a/rts/include/RtsAPI.h
+++ b/rts/include/RtsAPI.h
@@ -155,6 +155,8 @@ typedef struct GCDetails_ {
uint64_t mem_in_use_bytes;
// Total amount of data copied during this GC
uint64_t copied_bytes;
+ // Memory lost due to block fragmentation
+ uint64_t block_fragmentation_bytes;
// In parallel GC, the max amount of data copied by any one thread
uint64_t par_max_copied_bytes;
// In parallel GC, the amount of balanced data copied by all threads