Skip to content

Commit 50fd82a

Browse files
committed
Introduce LiveBytesStats. Cleanup
1 parent dc12596 commit 50fd82a

File tree

7 files changed

+88
-29
lines changed

7 files changed

+88
-29
lines changed

docs/userguide/src/migration/prefix.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,26 @@ Notes for the mmtk-core developers:
3030

3131
<!-- Insert new versions here -->
3232

33+
## 0.30.0
34+
35+
### `live_bytes_in_last_gc` returns a map for live bytes in each space
36+
37+
```admonish tldr
38+
The feature `count_live_bytes_in_gc` now collects live bytes statistics per space.
39+
Correspondingly, `memory_manager::live_bytes_in_last_gc` now returns a map for
40+
live bytes in each space.
41+
```
42+
43+
API changes:
44+
45+
- module `memory_manager`
46+
+ `live_bytes_in_last_gc` now returns a `HashMap<&'static str, LiveBytesStats>`. The keys are
47+
strings for space names, and the values are statistics for live bytes in the space.
48+
49+
See also:
50+
51+
- PR: <https://github.com/mmtk/mmtk-core/pull/1238>
52+
3353
## 0.28.0
3454

3555
### `handle_user_collection_request` returns `bool`

src/global_state.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ pub struct GlobalState {
4646
/// A counteer that keeps tracks of the number of bytes allocated by malloc
4747
#[cfg(feature = "malloc_counted_size")]
4848
pub(crate) malloc_bytes: AtomicUsize,
49-
/// This stores the size in bytes for all the live objects in last GC. This counter is only updated in the GC release phase.
49+
/// This stores the live bytes and the used bytes (by pages) for each space in last GC. This counter is only updated in the GC release phase.
5050
#[cfg(feature = "count_live_bytes_in_gc")]
51-
pub(crate) live_bytes_in_last_gc: AtomicRefCell<HashMap<&'static str, usize>>,
51+
pub(crate) live_bytes_in_last_gc: AtomicRefCell<HashMap<&'static str, LiveBytesStats>>,
5252
}
5353

5454
impl GlobalState {
@@ -216,3 +216,16 @@ pub enum GcStatus {
216216
GcPrepare,
217217
GcProper,
218218
}
219+
220+
/// Statistics for the live bytes in the last GC. The statistics is per space.
221+
#[derive(Copy, Clone, Debug)]
222+
#[cfg(feature = "count_live_bytes_in_gc")]
223+
pub struct LiveBytesStats {
224+
/// Total accumulated bytes of live objects in the space.
225+
pub live_bytes: usize,
226+
/// Total pages used by the space.
227+
pub used_pages: usize,
228+
/// Total bytes used by the space, computed from `used_pages`.
229+
/// The ratio of live_bytes and used_bytes reflects the utilization of the memory in the space.
230+
pub used_bytes: usize,
231+
}

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ pub(crate) use mmtk::MMAPPER;
4646
pub use mmtk::MMTK;
4747

4848
mod global_state;
49+
#[cfg(feature = "count_live_bytes_in_gc")]
50+
pub use crate::global_state::LiveBytesStats;
4951

5052
mod policy;
5153

src/memory_manager.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,14 +534,18 @@ pub fn free_bytes<VM: VMBinding>(mmtk: &MMTK<VM>) -> usize {
534534
mmtk.get_plan().get_free_pages() << LOG_BYTES_IN_PAGE
535535
}
536536

537-
/// Return the size of all the live objects in bytes in the last GC. MMTk usually accounts for memory in pages.
537+
/// Return a hash map for live bytes statistics in the last GC for each space.
538+
///
539+
/// MMTk usually accounts for memory in pages by each space.
538540
/// This is a special method that we count the size of every live object in a GC, and sum up the total bytes.
539-
/// We provide this method so users can compare with `used_bytes` (which does page accounting), and know if
540-
/// the heap is fragmented.
541+
/// We provide this method so users can use [`crate::LiveBytesStats`] to know if
542+
/// the space is fragmented.
541543
/// The value returned by this method is only updated when we finish tracing in a GC. A recommended timing
542544
/// to call this method is at the end of a GC (e.g. when the runtime is about to resume threads).
543545
#[cfg(feature = "count_live_bytes_in_gc")]
544-
pub fn live_bytes_in_last_gc<VM: VMBinding>(mmtk: &MMTK<VM>) -> HashMap<&'static str, usize> {
546+
pub fn live_bytes_in_last_gc<VM: VMBinding>(
547+
mmtk: &MMTK<VM>,
548+
) -> HashMap<&'static str, crate::LiveBytesStats> {
545549
mmtk.state.live_bytes_in_last_gc.borrow().clone()
546550
}
547551

src/mmtk.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ use crate::util::statistics::stats::Stats;
2626
use crate::vm::ReferenceGlue;
2727
use crate::vm::VMBinding;
2828
use std::cell::UnsafeCell;
29+
#[cfg(feature = "count_live_bytes_in_gc")]
30+
use std::collections::HashMap;
2931
use std::default::Default;
3032
use std::sync::atomic::{AtomicBool, Ordering};
3133
use std::sync::Arc;
@@ -526,4 +528,34 @@ impl<VM: VMBinding> MMTK<VM> {
526528
space.enumerate_objects(&mut enumerator);
527529
})
528530
}
531+
532+
/// Aggregate a hash map of live bytes per space with the space stats to produce
533+
/// a map of [`crate::liveByteStats`] for the spaces.
534+
#[cfg(feature = "count_live_bytes_in_gc")]
535+
pub(crate) fn aggregate_live_bytes_in_last_gc(
536+
&self,
537+
live_bytes_per_space: HashMap<&'static str, usize>,
538+
) -> HashMap<&'static str, crate::LiveBytesStats> {
539+
use crate::policy::space::Space;
540+
let mut ret = HashMap::new();
541+
self.get_plan().for_each_space(&mut |space: &dyn Space<VM>| {
542+
let space_name = space.get_name();
543+
let used_pages = space.reserved_pages();
544+
if used_pages != 0 {
545+
let used_bytes = space.reserved_pages() << crate::util::constants::LOG_BYTES_IN_PAGE;
546+
let live_bytes = *live_bytes_per_space.get(space_name).unwrap_or(&0);
547+
debug_assert!(
548+
live_bytes <= used_bytes,
549+
"Live bytes of objects in {} ({} bytes) is larger than used pages ({} bytes), something is wrong.",
550+
space_name, live_bytes, used_bytes
551+
);
552+
ret.insert(space_name, crate::LiveBytesStats {
553+
live_bytes,
554+
used_pages,
555+
used_bytes,
556+
});
557+
}
558+
});
559+
return ret;
560+
}
529561
}

src/scheduler/gc_work.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ impl<C: GCWorkContext + 'static> GCWork<C::VM> for Release<C> {
160160
.scheduler
161161
.worker_group
162162
.get_and_clear_worker_live_bytes();
163-
*mmtk.state.live_bytes_in_last_gc.borrow_mut() = live_bytes;
163+
*mmtk.state.live_bytes_in_last_gc.borrow_mut() =
164+
mmtk.aggregate_live_bytes_in_last_gc(live_bytes);
164165
}
165166
}
166167
}

src/scheduler/scheduler.rs

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -555,28 +555,15 @@ impl<VM: VMBinding> GCWorkScheduler<VM> {
555555

556556
#[cfg(feature = "count_live_bytes_in_gc")]
557557
{
558-
use crate::policy::space::Space;
559-
let live_bytes_per_space = mmtk.state.live_bytes_in_last_gc.borrow();
560-
mmtk.get_plan().for_each_space(&mut |space: &dyn Space<VM>| {
561-
let space_name = space.get_name();
562-
let used_pages = space.reserved_pages();
563-
if used_pages != 0 {
564-
let used_bytes = space.reserved_pages() << crate::util::constants::LOG_BYTES_IN_PAGE;
565-
let live_bytes = *live_bytes_per_space.get(space_name).unwrap_or(&0);
566-
debug_assert!(
567-
live_bytes <= used_bytes,
568-
"Live bytes of objects in {} ({} bytes) is larger than used pages ({} bytes), something is wrong.",
569-
space_name, live_bytes, used_bytes
570-
);
571-
info!(
572-
"{} = {} bytes ({:.1}% of {} used pages)",
573-
space_name,
574-
live_bytes,
575-
live_bytes as f64 * 100.0 / used_bytes as f64,
576-
used_pages
577-
);
578-
}
579-
})
558+
for (space_name, &stats) in mmtk.state.live_bytes_in_last_gc.borrow().iter() {
559+
info!(
560+
"{} = {} bytes ({:.1}% of {} used pages)",
561+
space_name,
562+
stats.live_bytes,
563+
stats.live_bytes as f64 * 100.0 / stats.used_bytes as f64,
564+
stats.used_bytes,
565+
);
566+
}
580567
}
581568

582569
#[cfg(feature = "extreme_assertions")]

0 commit comments

Comments
 (0)