From 8907355da8431d926c685edca6d144e04cf35f21 Mon Sep 17 00:00:00 2001 From: starunvs Date: Mon, 21 Jul 2025 11:10:01 +0800 Subject: [PATCH] fix the inconsistency of the old space's dump message Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/ICNM3K Change-Id: Icf6e63586fea85f7b8e0a1a337db089aed03a1d3 Signed-off-by: starunvs --- .../heap/allocator/region_space.h | 10 ++++ common_components/heap/collector/gc_stats.h | 56 +++++++++++++++++++ .../heap/collector/trace_collector.cpp | 22 ++++++-- .../heap/collector/trace_collector.h | 4 -- common_components/heap/space/old_space.cpp | 26 ++++++--- common_components/heap/space/old_space.h | 5 ++ common_components/heap/space/young_space.h | 2 +- 7 files changed, 109 insertions(+), 16 deletions(-) diff --git a/common_components/heap/allocator/region_space.h b/common_components/heap/allocator/region_space.h index 18f143ae40..a00bd8b17d 100755 --- a/common_components/heap/allocator/region_space.h +++ b/common_components/heap/allocator/region_space.h @@ -129,6 +129,16 @@ public: return youngSpace_.GetRecentAllocatedSize() + regionManager_.GetRecentAllocatedSize(); } + inline size_t GetRecentYoungAllocatedSize() const + { + return youngSpace_.GetRecentAllocatedSize(); + } + + inline size_t GetRecentOldAllocatedSize() const + { + return oldSpace_.GetRecentAllocatedSize(); + } + // size of objects survived in previous gc. size_t GetSurvivedSize() const override { diff --git a/common_components/heap/collector/gc_stats.h b/common_components/heap/collector/gc_stats.h index 4e2e87a6c8..173acd2535 100755 --- a/common_components/heap/collector/gc_stats.h +++ b/common_components/heap/collector/gc_stats.h @@ -28,6 +28,11 @@ #include "common_interfaces/base_runtime.h" namespace common { + +// number of nanoseconds in a microsecond. +constexpr uint64_t NS_PER_US = 1000; +constexpr uint64_t NS_PER_S = 1000000000; + // statistics for previous gc. class GCStats { public: @@ -62,6 +67,49 @@ public: void IncreaseAccumulatedFreeSize(size_t size) { accumulatedFreeSize += size; } + void UpdateAllocationSize(size_t youngSize, size_t oldSize) + { + youngAllocatedSinceLastGC = youngSize; + oldAllocatedSinceLastGC = oldSize; + + // check last gc reason + if (reason == GCReason::GC_REASON_YOUNG) { + youngAllocatedSinceLastFullGC += youngSize; + oldAllocatedSinceLastFullGC += oldSize; + } else { + youngAllocatedSinceLastFullGC = youngSize; + oldAllocatedSinceLastFullGC = oldSize; + } + } + + // Note: MB/s + double GetYoungAllocationRate() const + { + return (static_cast(youngAllocatedSinceLastGC) / MB) / + (static_cast(TimeUtil::NanoSeconds() - gcStartTime) / NS_PER_S); + } + + // Note: MB/s + double GetOldAllocationRate() const + { + return (static_cast(oldAllocatedSinceLastGC) / MB) / + (static_cast(TimeUtil::NanoSeconds() - gcStartTime) / NS_PER_S); + } + + // Note: MB/s + double GetYoungAllocationRateSinceLastFull() const + { + return (static_cast(youngAllocatedSinceLastFullGC) / MB) / + (static_cast(TimeUtil::NanoSeconds() - lastFullGcStartTime) / NS_PER_S); + } + + // Note: MB/s + double GetOldAllocationRateSinceLastFull() const + { + return (static_cast(oldAllocatedSinceLastFullGC) / MB) / + (static_cast(TimeUtil::NanoSeconds() - lastFullGcStartTime) / NS_PER_S); + } + static uint64_t prevGcStartTime; static uint64_t prevGcFinishTime; @@ -73,6 +121,14 @@ public: uint64_t gcStartTime; uint64_t gcEndTime; + uint64_t lastFullGcStartTime; + + // update before every GC start + size_t youngAllocatedSinceLastGC; + size_t oldAllocatedSinceLastGC; + size_t youngAllocatedSinceLastFullGC; + size_t oldAllocatedSinceLastFullGC; + uint64_t totalSTWTime; // total stw time(microseconds) uint64_t maxSTWTime; // max stw time(microseconds) diff --git a/common_components/heap/collector/trace_collector.cpp b/common_components/heap/collector/trace_collector.cpp index a2e7bd42b5..3004d98a37 100755 --- a/common_components/heap/collector/trace_collector.cpp +++ b/common_components/heap/collector/trace_collector.cpp @@ -582,6 +582,10 @@ void TraceCollector::PreGarbageCollection(bool isConcurrent) gcStats.gcStartTime = TimeUtil::NanoSeconds(); gcStats.totalSTWTime = 0; gcStats.maxSTWTime = 0; + + if (gcReason_ != GC_REASON_YOUNG) { + gcStats.lastFullGcStartTime = gcStats.gcStartTime; + } #if defined(GCINFO_DEBUG) && GCINFO_DEBUG DumpBeforeGC(); #endif @@ -714,11 +718,16 @@ void TraceCollector::RunGarbageCollection(uint64_t gcIndex, GCReason reason, GCT { gcReason_ = reason; gcType_ = gcType; + + auto &space = reinterpret_cast(theAllocator_); + space.DumpAllRegionStats("Begin GC log", gcReason_, gcType_); + + GCStats& gcStats = GetGCStats(); + gcStats.UpdateAllocationSize(space.GetRecentYoungAllocatedSize(), space.GetRecentOldAllocatedSize()); + auto gcReasonName = std::string(g_gcRequests[gcReason_].name); auto currentAllocatedSize = Heap::GetHeap().GetAllocatedSize(); auto currentThreshold = Heap::GetHeap().GetCollector().GetGCStats().GetThreshold(); - RegionSpace& space = reinterpret_cast(theAllocator_); - space.DumpAllRegionStats("Begin GC log", gcReason_, gcType_); OHOS_HITRACE(HITRACE_LEVEL_COMMERCIAL, "CMCGC::RunGarbageCollection", ( "GCReason:" + gcReasonName + ";GCType:" + GCTypeToString(gcType) + ";Sensitive:" + std::to_string(static_cast(Heap::GetHeap().GetSensitiveStatus())) + @@ -726,14 +735,19 @@ void TraceCollector::RunGarbageCollection(uint64_t gcIndex, GCReason reason, GCT ";Current Allocated:" + Pretty(currentAllocatedSize) + ";Current Threshold:" + Pretty(currentThreshold) + ";Current Native:" + Pretty(Heap::GetHeap().GetNotifiedNativeSize()) + - ";NativeThreshold:" + Pretty(Heap::GetHeap().GetNativeHeapThreshold()) + ";NativeThreshold:" + Pretty(Heap::GetHeap().GetNativeHeapThreshold()) + + ";Young Allocation Rate: " + std::to_string(stats.GetYoungAllocationRate()) + " MB/s" + + ";Old Allocation Rate: " + std::to_string(stats.GetOldAllocationRate()) + " MB/s" + + ";Young Allocation Rate[Full]: " + std::to_string(stats.GetYoungAllocationRateSinceLastFull()) + " MB/s" + + ";Old Allocation Rate[Full]: " + std::to_string(stats.GetOldAllocationRateSinceLastFull()) + " MB/s" ).c_str()); + // ---- <<< stats before current GC >>> ---- + // prevent other threads stop-the-world during GC. // this may be removed in the future. ScopedSTWLock stwLock; PreGarbageCollection(true); Heap::GetHeap().SetGCReason(reason); - GCStats& gcStats = GetGCStats(); DoGarbageCollection(); diff --git a/common_components/heap/collector/trace_collector.h b/common_components/heap/collector/trace_collector.h index 3f41128961..4d9a3242b2 100755 --- a/common_components/heap/collector/trace_collector.h +++ b/common_components/heap/collector/trace_collector.h @@ -34,10 +34,6 @@ using CArrayList = std::vector; template class GlobalStackQueue; -// number of nanoseconds in a microsecond. -constexpr uint64_t NS_PER_US = 1000; -constexpr uint64_t NS_PER_S = 1000000000; - // prefetch distance for mark. #define MACRO_MARK_PREFETCH_DISTANCE 16 // this macro is used for check when pre-compiling. constexpr int MARK_PREFETCH_DISTANCE = 16; // when it is changed, remember to change MACRO_MARK_PREFETCH_DISTANCE. diff --git a/common_components/heap/space/old_space.cpp b/common_components/heap/space/old_space.cpp index b49a01c0c0..ca8d668d79 100644 --- a/common_components/heap/space/old_space.cpp +++ b/common_components/heap/space/old_space.cpp @@ -21,14 +21,26 @@ namespace common { void OldSpace::DumpRegionStats() const { - size_t oldRegions = - tlOldRegionList_.GetRegionCount() + recentFullOldRegionList_.GetRegionCount() + oldRegionList_.GetRegionCount(); - size_t oldUnits = - tlOldRegionList_.GetUnitCount() + recentFullOldRegionList_.GetUnitCount() + oldRegionList_.GetUnitCount(); + size_t tlRegions = tlOldRegionList_.GetRegionCount(); + size_t tlUnits = tlOldRegionList_.GetUnitCount(); + size_t tlSize = tlUnits * RegionDesc::UNIT_SIZE; + size_t allocTLSize = tlOldRegionList_.GetAllocatedSize(); + + size_t recentFullRegions = recentFullOldRegionList_.GetRegionCount(); + size_t recentFullUnits = recentFullOldRegionList_.GetUnitCount(); + size_t recentFullSize = recentFullUnits * RegionDesc::UNIT_SIZE; + size_t allocRecentFullSize = recentFullOldRegionList_.GetAllocatedSize(); + + size_t oldRegions = oldRegionList_.GetRegionCount(); + size_t oldUnits = oldRegionList_.GetUnitCount(); size_t oldSize = oldUnits * RegionDesc::UNIT_SIZE; - size_t allocFromSize = GetAllocatedSize(); + size_t allocOldSize = oldRegionList_.GetAllocatedSize(); - VLOG(DEBUG, "\told-regions %zu: %zu units (%zu B, alloc %zu)", - oldRegions, oldUnits, oldSize, allocFromSize); + size_t units = tlUnits + recentFullUnits + oldUnits; + VLOG(DEBUG, "\told space units: %zu (%zu B)", units, units * RegionDesc::UNIT_SIZE); + VLOG(DEBUG, "\t tl-old-regions %zu: %zu units (%zu B, alloc %zu)", tlRegions, tlUnits, tlSize, allocTLSize); + VLOG(DEBUG, "\t recent-full-old regions %zu: %zu units (%zu B, alloc %zu)", recentFullRegions, recentFullUnits, + recentFullSize, allocRecentFullSize); + VLOG(DEBUG, "\t old regions %zu: %zu units (%zu B, alloc %zu)", oldRegions, oldUnits, oldSize, allocOldSize); } } // namespace common diff --git a/common_components/heap/space/old_space.h b/common_components/heap/space/old_space.h index 4028923c93..0a708936d1 100644 --- a/common_components/heap/space/old_space.h +++ b/common_components/heap/space/old_space.h @@ -37,6 +37,11 @@ public: void DumpRegionStats() const; + size_t GetRecentAllocatedSize() const + { + return tlOldRegionList_.GetAllocatedSize() + recentFullOldRegionList_.GetAllocatedSize(); + } + void AddThreadLocalRegion(RegionDesc* region) { tlOldRegionList_.PrependRegion(region, RegionDesc::RegionType::THREAD_LOCAL_OLD_REGION); diff --git a/common_components/heap/space/young_space.h b/common_components/heap/space/young_space.h index f507c6a9c2..daeb969fdc 100644 --- a/common_components/heap/space/young_space.h +++ b/common_components/heap/space/young_space.h @@ -85,7 +85,7 @@ public: size_t GetRecentAllocatedSize() const { - return recentFullRegionList_.GetAllocatedSize(); + return tlRegionList_.GetAllocatedSize() + recentFullRegionList_.GetAllocatedSize(); } void ClearAllGCInfo() -- Gitee