diff options
-rw-r--r-- | libraries/base/GHC/Stats.hsc | 7 | ||||
-rw-r--r-- | libraries/base/changelog.md | 1 | ||||
-rw-r--r-- | rts/Stats.c | 8 | ||||
-rw-r--r-- | rts/include/RtsAPI.h | 2 |
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 |