1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecmascript/mem/gc_stats.h" 17 18#include <iomanip> 19#include "ecmascript/mem/heap-inl.h" 20 21constexpr int DESCRIPTION_LENGTH = 25; 22constexpr int DATA_LENGTH = 8; 23 24#define STATS_DESCRIPTION_FORMAT(description) \ 25 std::left << std::setw(DESCRIPTION_LENGTH) << (description) 26 27#define STATS_DATA_FORMAT(data) \ 28 std::setw(DATA_LENGTH) << (data) 29 30namespace panda::ecmascript { 31void GCStats::PrintStatisticResult() 32{ 33 LOG_GC(INFO) << "/******************* GCStats statistic: *******************/"; 34 PrintGCSummaryStatistic(GCType::PARTIAL_EDEN_GC); 35 PrintGCSummaryStatistic(GCType::PARTIAL_YOUNG_GC); 36 PrintGCSummaryStatistic(GCType::PARTIAL_OLD_GC); 37 PrintGCSummaryStatistic(GCType::COMPRESS_GC); 38 PrintGCMemoryStatistic(); 39} 40 41void GCStats::PrintGCStatistic() 42{ 43 ASSERT(heap_ != nullptr); 44 ASSERT(heap_->GetEcmaVM() != nullptr); 45 if (heap_->GetEcmaVM()->GetJSOptions().EnableGCTracer() || CheckIfLongTimePause()) { 46 LOG_GC(INFO) << " [ " << GetGCTypeName() << " ] " 47 << sizeToMB(recordData_[(uint8_t)RecordData::START_OBJ_SIZE]) << " (" 48 << sizeToMB(recordData_[(uint8_t)RecordData::START_COMMIT_SIZE]) << ") -> " 49 << sizeToMB(recordData_[(uint8_t)RecordData::END_OBJ_SIZE]) << " (" 50 << sizeToMB(recordData_[(uint8_t)RecordData::END_COMMIT_SIZE]) << ") MB, " 51 << scopeDuration_[Scope::ScopeId::TotalGC] << "(+" 52 << GetConcurrrentMarkDuration() 53 << ")ms, " << GCReasonToString(reason_); 54 LOG_GC(INFO) << "IsInBackground: " << heap_->IsInBackground() << "; " 55 << "SensitiveStatus: " << static_cast<int>(heap_->GetSensitiveStatus()) << "; " 56 << "OnStartupEvent: " << heap_->OnStartupEvent() << "; " 57 << "BundleName: " << heap_->GetEcmaVM()->GetBundleName() << ";"; 58 // print verbose gc statsistics 59 PrintVerboseGCStatistic(); 60 } 61 InitializeRecordList(); 62} 63 64const char *GCStats::GCReasonToString() 65{ 66 return GCReasonToString(reason_); 67} 68 69const char *GCStats::GCReasonToString(GCReason reason) 70{ 71 switch (reason) { 72 case GCReason::ALLOCATION_LIMIT: 73 return "Memory reach limit"; 74 case GCReason::ALLOCATION_FAILED: 75 return "Allocate object failed"; 76 case GCReason::IDLE: 77 return "Idle time task"; 78 case GCReason::SWITCH_BACKGROUND: 79 return "Switch to background"; 80 case GCReason::EXTERNAL_TRIGGER: 81 return "Externally triggered"; 82 case GCReason::WORKER_DESTRUCTION: 83 return "Worker Destruction"; 84 case GCReason::TRIGGER_BY_JS: 85 return "Trigger by JS"; 86 case GCReason::TRIGGER_BY_ARKUI: 87 return "Trigger by ArkUI"; 88 case GCReason::TRIGGER_BY_ABILITY: 89 return "Trigger by AbilityRuntime"; 90 case GCReason::TRIGGER_BY_MEM_TOOLS: 91 return "Trigger by Mem tools"; 92 case GCReason::TRIGGER_BY_TASKPOOL: 93 return "Trigger by taskPool"; 94 default: 95 return "Other"; 96 } 97} 98 99float GCStats::GetConcurrrentMarkDuration() 100{ 101 return concurrentMark_ ? scopeDuration_[Scope::ScopeId::ConcurrentMark] : 0; 102} 103 104void GCStats::PrintVerboseGCStatistic() 105{ 106 PrintGCDurationStatistic(); 107 PrintGCMemoryStatistic(); 108 PrintGCSummaryStatistic(); 109} 110 111void GCStats::PrintGCMemoryStatistic() 112{ 113 NativeAreaAllocator *nativeAreaAllocator = heap_->GetNativeAreaAllocator(); 114 HeapRegionAllocator *heapRegionAllocator = heap_->GetHeapRegionAllocator(); 115 LOG_GC(INFO) << "/****************** GC Memory statistic: *****************/"; 116 LOG_GC(INFO) << "AllSpaces used:" 117 << STATS_DATA_FORMAT(sizeToKB(heap_->GetHeapObjectSize())) << "KB" 118 << " committed:" 119 << STATS_DATA_FORMAT(sizeToKB(heap_->GetCommittedSize())) << "KB\n" 120 << "EdenSpace used:" 121 << STATS_DATA_FORMAT(sizeToKB(heap_->GetEdenSpace()->GetHeapObjectSize())) << "KB" 122 << " committed:" 123 << STATS_DATA_FORMAT(sizeToKB(heap_->GetEdenSpace()->GetCommittedSize())) << "KB\n" 124 << "ActiveSemiSpace used:" 125 << STATS_DATA_FORMAT(sizeToKB(heap_->GetNewSpace()->GetHeapObjectSize())) << "KB" 126 << " committed:" 127 << STATS_DATA_FORMAT(sizeToKB(heap_->GetNewSpace()->GetCommittedSize())) << "KB\n" 128 << "OldSpace used:" 129 << STATS_DATA_FORMAT(sizeToKB(heap_->GetOldSpace()->GetHeapObjectSize())) << "KB" 130 << " committed:" 131 << STATS_DATA_FORMAT(sizeToKB(heap_->GetOldSpace()->GetCommittedSize())) << "KB\n" 132 << "HugeObjectSpace used:" 133 << STATS_DATA_FORMAT(sizeToKB(heap_->GetHugeObjectSpace()->GetHeapObjectSize())) << "KB" 134 << " committed:" 135 << STATS_DATA_FORMAT(sizeToKB(heap_->GetHugeObjectSpace()->GetCommittedSize())) << "KB\n" 136 << "NonMovableSpace used:" 137 << STATS_DATA_FORMAT(sizeToKB(heap_->GetNonMovableSpace()->GetHeapObjectSize())) << "KB" 138 << " committed:" 139 << STATS_DATA_FORMAT(sizeToKB(heap_->GetNonMovableSpace()->GetCommittedSize())) << "KB\n" 140 << "MachineCodeSpace used:" 141 << STATS_DATA_FORMAT(sizeToKB(heap_->GetMachineCodeSpace()->GetHeapObjectSize())) << "KB" 142 << " committed:" 143 << STATS_DATA_FORMAT(sizeToKB(heap_->GetMachineCodeSpace()->GetCommittedSize())) << "KB\n" 144 << "HugeMachineCodeSpace used:" 145 << STATS_DATA_FORMAT(sizeToKB(heap_->GetHugeMachineCodeSpace()->GetHeapObjectSize())) << "KB" 146 << " committed:" 147 << STATS_DATA_FORMAT(sizeToKB(heap_->GetHugeMachineCodeSpace()->GetCommittedSize())) << "KB\n" 148 << "SnapshotSpace used:" 149 << STATS_DATA_FORMAT(sizeToKB(heap_->GetSnapshotSpace()->GetHeapObjectSize())) << "KB" 150 << " committed:" 151 << STATS_DATA_FORMAT(sizeToKB(heap_->GetSnapshotSpace()->GetCommittedSize())) << "KB\n" 152 << "AppSpawnSpace used:" 153 << STATS_DATA_FORMAT(sizeToKB(heap_->GetAppSpawnSpace()->GetHeapObjectSize())) << "KB" 154 << " committed:" 155 << STATS_DATA_FORMAT(sizeToKB(heap_->GetAppSpawnSpace()->GetCommittedSize())) << "KB"; 156 157 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("Anno memory usage size:") 158 << STATS_DATA_FORMAT(sizeToMB(heapRegionAllocator->GetAnnoMemoryUsage())) << "MB\n" 159 << STATS_DESCRIPTION_FORMAT("Native memory usage size:") 160 << STATS_DATA_FORMAT(sizeToMB(nativeAreaAllocator->GetNativeMemoryUsage())) << "MB\n" 161 << STATS_DESCRIPTION_FORMAT("NativeBindingSize:") 162 << STATS_DATA_FORMAT(sizeToKB(heap_->GetNativeBindingSize())) << "KB\n" 163 << STATS_DESCRIPTION_FORMAT("ArrayBufferNativeSize:") 164 << STATS_DATA_FORMAT(sizeToKB(heap_->GetNativeAreaAllocator()->GetArrayBufferNativeSize())) 165 << "KB\n" 166 << STATS_DESCRIPTION_FORMAT("RegExpByteCodeNativeSize:") 167 << STATS_DATA_FORMAT(sizeToKB(heap_->GetNativeAreaAllocator()->GetRegExpNativeSize())) << "KB\n" 168 << STATS_DESCRIPTION_FORMAT("ChunkNativeSize:") 169 << STATS_DATA_FORMAT(sizeToKB(heap_->GetNativeAreaAllocator()->GetChunkNativeSize())) << "KB"; 170 switch (gcType_) { 171 case GCType::PARTIAL_EDEN_GC: { 172 size_t commitSize = GetRecordData(RecordData::EDEN_COMMIT_SIZE); 173 double copiedRate = commitSize == 0 ? 0 : (double(GetRecordData(RecordData::EDEN_ALIVE_SIZE)) / commitSize); 174 double premotedRate = 175 commitSize == 0 ? 0 : (double(GetRecordData(RecordData::EDEN_PROMOTE_SIZE)) / commitSize); 176 double survivalRate = std::min(copiedRate + premotedRate, 1.0); 177 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("Eden copied rate:") << STATS_DATA_FORMAT(copiedRate) << "\n" 178 << STATS_DESCRIPTION_FORMAT("Eden promoted rate:") << STATS_DATA_FORMAT(premotedRate) << "\n" 179 << STATS_DESCRIPTION_FORMAT("Eden survival rate:") << STATS_DATA_FORMAT(survivalRate); 180 break; 181 } 182 case GCType::PARTIAL_YOUNG_GC: { 183 double copiedRate = double(GetRecordData(RecordData::YOUNG_ALIVE_SIZE)) / 184 GetRecordData(RecordData::YOUNG_COMMIT_SIZE); 185 double premotedRate = double(GetRecordData(RecordData::YOUNG_PROMOTE_SIZE)) / 186 GetRecordData(RecordData::YOUNG_COMMIT_SIZE); 187 double survivalRate = std::min(copiedRate + premotedRate, 1.0); 188 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("Young copied rate:") << STATS_DATA_FORMAT(copiedRate) << "\n" 189 << STATS_DESCRIPTION_FORMAT("Young promoted rate:") << STATS_DATA_FORMAT(premotedRate) << "\n" 190 << STATS_DESCRIPTION_FORMAT("Young survival rate:") << STATS_DATA_FORMAT(survivalRate); 191 break; 192 } 193 case GCType::PARTIAL_OLD_GC: { 194 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("Heap alive rate:") 195 << STATS_DATA_FORMAT(double(GetRecordData(RecordData::OLD_ALIVE_SIZE)) / 196 GetRecordData(RecordData::OLD_COMMIT_SIZE)); 197 break; 198 } 199 case GCType::COMPRESS_GC: { 200 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("Heap alive rate:") 201 << STATS_DATA_FORMAT(double(GetRecordData(RecordData::COMPRESS_ALIVE_SIZE)) / 202 GetRecordData(RecordData::COMPRESS_COMMIT_SIZE)); 203 break; 204 } 205 default: 206 break; 207 } 208} 209 210void GCStats::PrintGCDurationStatistic() 211{ 212 LOG_GC(INFO) << "/***************** GC Duration statistic: ****************/"; 213 switch (gcType_) { 214 case GCType::PARTIAL_EDEN_GC: 215 case GCType::PARTIAL_YOUNG_GC: 216 case GCType::PARTIAL_OLD_GC: 217 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("TotalGC:") 218 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::TotalGC]) << "ms\n" 219 << STATS_DESCRIPTION_FORMAT("Initialize:") 220 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Initialize]) << "ms\n" 221 << STATS_DESCRIPTION_FORMAT("Mark:") 222 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Mark]) << "ms\n" 223 << STATS_DESCRIPTION_FORMAT("MarkRoots:") 224 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::MarkRoots]) << "ms\n" 225 << STATS_DESCRIPTION_FORMAT("ConcurrentMark pause:") 226 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::ConcurrentMark]) << "ms\n" 227 << STATS_DESCRIPTION_FORMAT("WaitConcurrentMarkFinish:") 228 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::WaitConcurrentMarkFinished]) << "ms\n" 229 << STATS_DESCRIPTION_FORMAT("ReMark:") 230 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::ReMark]) << "ms\n" 231 << STATS_DESCRIPTION_FORMAT("ProcessSharedGCRSetWorkList:") 232 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::ProcessSharedGCRSetWorkList]) << "ms\n" 233 << STATS_DESCRIPTION_FORMAT("Sweep:") 234 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Sweep]) << "ms\n" 235 << STATS_DESCRIPTION_FORMAT("ClearNativeObject:") 236 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::ClearNativeObject]) << "ms\n" 237 << STATS_DESCRIPTION_FORMAT("Evacuate:") 238 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Evacuate]) << "ms\n" 239 << STATS_DESCRIPTION_FORMAT("UpdateReference:") 240 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::UpdateReference]) << "ms\n" 241 << STATS_DESCRIPTION_FORMAT("UpdateWeekRef:") 242 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::UpdateWeekRef]) << "ms\n" 243 << STATS_DESCRIPTION_FORMAT("UpdateRoot:") 244 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::UpdateRoot]) << "ms\n" 245 << STATS_DESCRIPTION_FORMAT("ProceeWorkload:") 246 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::ProceeWorkload]) << "ms\n" 247 << STATS_DESCRIPTION_FORMAT("EvacuateSpace:") 248 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::EvacuateSpace]) << "ms\n" 249 << STATS_DESCRIPTION_FORMAT("EvacuateRegion:") 250 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::EvacuateRegion]) << "ms\n" 251 << STATS_DESCRIPTION_FORMAT("WaitFinish:") 252 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::WaitFinish]) << "ms\n" 253 << STATS_DESCRIPTION_FORMAT("Finish:") 254 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Finish]) << "ms"; 255 break; 256 case GCType::COMPRESS_GC: 257 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("TotalGC:") 258 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::TotalGC]) << "ms\n" 259 << STATS_DESCRIPTION_FORMAT("ProcessSharedGCRSetWorkList:") 260 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::ProcessSharedGCRSetWorkList]) << "ms\n" 261 << STATS_DESCRIPTION_FORMAT("Initialize:") 262 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Initialize]) << "ms\n" 263 << STATS_DESCRIPTION_FORMAT("Mark:") 264 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Mark]) << "ms\n" 265 << STATS_DESCRIPTION_FORMAT("MarkRoots:") 266 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::MarkRoots]) << "ms\n" 267 << STATS_DESCRIPTION_FORMAT("Sweep:") 268 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Sweep]) << "ms\n" 269 << STATS_DESCRIPTION_FORMAT("Finish:") 270 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Finish]) << "ms"; 271 break; 272 default: 273 break; 274 } 275} 276 277bool GCStats::CheckIfNeedPrint(GCType type) 278{ 279 uint32_t gcCount = 0; 280 switch (type) { 281 case GCType::PARTIAL_EDEN_GC: 282 gcCount = GetRecordData(RecordData::EDEN_COUNT); 283 break; 284 case GCType::PARTIAL_YOUNG_GC: 285 gcCount = GetRecordData(RecordData::YOUNG_COUNT); 286 break; 287 case GCType::PARTIAL_OLD_GC: 288 gcCount = GetRecordData(RecordData::OLD_COUNT); 289 break; 290 case GCType::COMPRESS_GC: 291 gcCount = GetRecordData(RecordData::COMPRESS_COUNT); 292 break; 293 default: 294 break; 295 } 296 297 if (gcCount > 0) { 298 return true; 299 } 300 return false; 301} 302 303void GCStats::PrintGCSummaryStatistic(GCType type) 304{ 305 if (type != GCType::START && !CheckIfNeedPrint(type)) { 306 return; 307 } else { 308 type = type == GCType::START ? gcType_ : type; 309 } 310 LOG_GC(INFO) << "/***************** GC summary statistic: *****************/"; 311 switch (type) { 312 case GCType::PARTIAL_EDEN_GC: { 313 size_t commitSize = GetRecordData(RecordData::EDEN_TOTAL_COMMIT); 314 double copiedRate = 315 commitSize == 0 ? 0 : (double(GetRecordData(RecordData::EDEN_TOTAL_ALIVE)) / commitSize); 316 double promotedRate = 317 commitSize == 0 ? 0 : (double(GetRecordData(RecordData::EDEN_TOTAL_PROMOTE)) / commitSize); 318 double survivalRate = std::min(copiedRate + promotedRate, 1.0); 319 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("EdenGC occurs count") 320 << STATS_DATA_FORMAT(GetRecordData(RecordData::EDEN_COUNT)) << "\n" 321 << STATS_DESCRIPTION_FORMAT("EdenGC max pause:") 322 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::EDEN_MAX_PAUSE)) << "ms\n" 323 << STATS_DESCRIPTION_FORMAT("EdenGC min pause:") 324 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::EDEN_MIN_PAUSE)) << "ms\n" 325 << STATS_DESCRIPTION_FORMAT("EdenGC average pause:") 326 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::EDEN_TOTAL_PAUSE) / 327 GetRecordData(RecordData::EDEN_COUNT)) << "ms\n" 328 << STATS_DESCRIPTION_FORMAT("Eden average copied rate:") << STATS_DATA_FORMAT(copiedRate) << "\n" 329 << STATS_DESCRIPTION_FORMAT("Eden average promoted rate:") << STATS_DATA_FORMAT(promotedRate) << "\n" 330 << STATS_DESCRIPTION_FORMAT("Eden average survival rate:") << STATS_DATA_FORMAT(survivalRate); 331 break; 332 } 333 case GCType::PARTIAL_YOUNG_GC: { 334 double copiedRate = double(GetRecordData(RecordData::YOUNG_TOTAL_ALIVE)) / 335 GetRecordData(RecordData::YOUNG_TOTAL_COMMIT); 336 double promotedRate = double(GetRecordData(RecordData::YOUNG_TOTAL_PROMOTE)) / 337 GetRecordData(RecordData::YOUNG_TOTAL_COMMIT); 338 double survivalRate = std::min(copiedRate + promotedRate, 1.0); 339 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("YoungGC occurs count") 340 << STATS_DATA_FORMAT(GetRecordData(RecordData::YOUNG_COUNT)) << "\n" 341 << STATS_DESCRIPTION_FORMAT("YoungGC max pause:") 342 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::YOUNG_MAX_PAUSE)) << "ms\n" 343 << STATS_DESCRIPTION_FORMAT("YoungGC min pause:") 344 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::YOUNG_MIN_PAUSE)) << "ms\n" 345 << STATS_DESCRIPTION_FORMAT("YoungGC average pause:") 346 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::YOUNG_TOTAL_PAUSE) / 347 GetRecordData(RecordData::YOUNG_COUNT)) << "ms\n" 348 << STATS_DESCRIPTION_FORMAT("Young average copied rate:") << STATS_DATA_FORMAT(copiedRate) << "\n" 349 << STATS_DESCRIPTION_FORMAT("Young average promoted rate:") << STATS_DATA_FORMAT(promotedRate) << "\n" 350 << STATS_DESCRIPTION_FORMAT("Young average survival rate:") << STATS_DATA_FORMAT(survivalRate); 351 break; 352 } 353 case GCType::PARTIAL_OLD_GC: { 354 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("OldGC occurs count") 355 << STATS_DATA_FORMAT(GetRecordData(RecordData::OLD_COUNT)) << "\n" 356 << STATS_DESCRIPTION_FORMAT("OldGC max pause:") 357 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::OLD_MAX_PAUSE)) << "ms\n" 358 << STATS_DESCRIPTION_FORMAT("OldGC min pause:") 359 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::OLD_MIN_PAUSE)) << "ms\n" 360 << STATS_DESCRIPTION_FORMAT("OldGC average pause:") 361 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::OLD_TOTAL_PAUSE) / 362 GetRecordData(RecordData::OLD_COUNT)) << "ms\n" 363 << STATS_DESCRIPTION_FORMAT("Heap average alive rate:") 364 << STATS_DATA_FORMAT(double(GetRecordData(RecordData::OLD_TOTAL_ALIVE)) / 365 GetRecordData(RecordData::OLD_TOTAL_COMMIT)); 366 break; 367 } 368 case GCType::COMPRESS_GC: { 369 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("CompressGC occurs count") 370 << STATS_DATA_FORMAT(GetRecordData(RecordData::COMPRESS_COUNT)) << "\n" 371 << STATS_DESCRIPTION_FORMAT("CompressGC max pause:") 372 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::COMPRESS_MAX_PAUSE)) << "ms\n" 373 << STATS_DESCRIPTION_FORMAT("CompressGC min pause:") 374 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::COMPRESS_MIN_PAUSE)) << "ms\n" 375 << STATS_DESCRIPTION_FORMAT("CompressGC average pause:") 376 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::COMPRESS_TOTAL_PAUSE) / 377 GetRecordData(RecordData::COMPRESS_COUNT)) << "ms\n" 378 << STATS_DESCRIPTION_FORMAT("Heap average alive rate:") 379 << STATS_DATA_FORMAT(double(GetRecordData(RecordData::COMPRESS_TOTAL_ALIVE)) / 380 GetRecordData(RecordData::COMPRESS_TOTAL_COMMIT)); 381 break; 382 } 383 default: 384 break; 385 } 386} 387 388size_t GCStats::GetAccumulatedAllocateSize() 389{ 390 return accumulatedFreeSize_ + heap_->GetHeapObjectSize(); 391} 392 393void GCStats::RecordStatisticBeforeGC(TriggerGCType gcType, GCReason reason) 394{ 395 SetRecordData(RecordData::START_OBJ_SIZE, heap_->GetHeapObjectSize()); 396 SetRecordData(RecordData::START_COMMIT_SIZE, heap_->GetCommittedSize()); 397 SetRecordData(RecordData::START_EDEN_OBJ_SIZE, heap_->GetEdenSpace()->GetHeapObjectSize()); 398 SetRecordData(RecordData::START_YOUNG_OBJ_SIZE, heap_->GetNewSpace()->GetHeapObjectSize()); 399 SetRecordData(RecordData::START_NATIVE_POINTER_NUM, heap_->GetNativePointerListSize()); 400 gcType_ = GetGCType(gcType); 401 reason_ = reason; 402 403 switch (gcType_) { 404 case GCType::PARTIAL_EDEN_GC: { 405 size_t edenCommitSize = heap_->GetEdenSpace()->GetCommittedSize(); 406 SetRecordData(RecordData::EDEN_COMMIT_SIZE, edenCommitSize); 407 IncreaseRecordData(RecordData::EDEN_TOTAL_COMMIT, edenCommitSize); 408 break; 409 } 410 case GCType::PARTIAL_YOUNG_GC: { 411 size_t youngCommitSize = 412 heap_->GetNewSpace()->GetCommittedSize() + heap_->GetEdenSpace()->GetCommittedSize(); 413 SetRecordData(RecordData::YOUNG_COMMIT_SIZE, youngCommitSize); 414 IncreaseRecordData(RecordData::YOUNG_TOTAL_COMMIT, youngCommitSize); 415 break; 416 } 417 case GCType::PARTIAL_OLD_GC: { 418 size_t oldCommitSize = heap_->GetCommittedSize(); 419 SetRecordData(RecordData::OLD_COMMIT_SIZE, oldCommitSize); 420 IncreaseRecordData(RecordData::OLD_TOTAL_COMMIT, oldCommitSize); 421 break; 422 } 423 case GCType::COMPRESS_GC: { 424 size_t compressCommitSize = heap_->GetCommittedSize(); 425 SetRecordData(RecordData::COMPRESS_COMMIT_SIZE, compressCommitSize); 426 IncreaseRecordData(RecordData::COMPRESS_TOTAL_COMMIT, compressCommitSize); 427 break; 428 } 429 default: 430 break; 431 } 432} 433 434void GCStats::RecordStatisticAfterGC() 435{ 436 SetRecordData(RecordData::END_OBJ_SIZE, heap_->GetHeapObjectSize()); 437 SetRecordData(RecordData::END_COMMIT_SIZE, heap_->GetCommittedSize()); 438 439 float duration = scopeDuration_[Scope::ScopeId::TotalGC]; 440 switch (gcType_) { 441 case GCType::PARTIAL_EDEN_GC: { 442 if (GetRecordData(RecordData::EDEN_COUNT) == 0) { 443 SetRecordDuration(RecordDuration::EDEN_MIN_PAUSE, duration); 444 SetRecordDuration(RecordDuration::EDEN_MAX_PAUSE, duration); 445 } else { 446 SetRecordDuration(RecordDuration::EDEN_MIN_PAUSE, 447 std::min(GetRecordDuration(RecordDuration::EDEN_MIN_PAUSE), duration)); 448 SetRecordDuration(RecordDuration::EDEN_MAX_PAUSE, 449 std::max(GetRecordDuration(RecordDuration::EDEN_MAX_PAUSE), duration)); 450 } 451 IncreaseRecordData(RecordData::EDEN_COUNT); 452 IncreaseRecordDuration(RecordDuration::EDEN_TOTAL_PAUSE, duration); 453 size_t edenToYoungSize = heap_->GetEdenToYoungSize(); 454 SetRecordData(RecordData::EDEN_ALIVE_SIZE, edenToYoungSize); 455 IncreaseRecordData(RecordData::EDEN_TOTAL_ALIVE, edenToYoungSize); 456 size_t promotedSize = heap_->GetPromotedSize(); 457 SetRecordData(RecordData::EDEN_PROMOTE_SIZE, promotedSize); 458 IncreaseRecordData(RecordData::EDEN_TOTAL_PROMOTE, promotedSize); 459 break; 460 } 461 case GCType::PARTIAL_YOUNG_GC: { 462 if (GetRecordData(RecordData::YOUNG_COUNT) == 0) { 463 SetRecordDuration(RecordDuration::YOUNG_MIN_PAUSE, duration); 464 SetRecordDuration(RecordDuration::YOUNG_MAX_PAUSE, duration); 465 } else { 466 SetRecordDuration(RecordDuration::YOUNG_MIN_PAUSE, 467 std::min(GetRecordDuration(RecordDuration::YOUNG_MIN_PAUSE), duration)); 468 SetRecordDuration(RecordDuration::YOUNG_MAX_PAUSE, 469 std::max(GetRecordDuration(RecordDuration::YOUNG_MAX_PAUSE), duration)); 470 } 471 IncreaseRecordData(RecordData::YOUNG_COUNT); 472 IncreaseRecordDuration(RecordDuration::YOUNG_TOTAL_PAUSE, duration); 473 size_t youngAliveSize = heap_->GetNewSpace()->GetHeapObjectSize(); 474 SetRecordData(RecordData::YOUNG_ALIVE_SIZE, youngAliveSize); 475 IncreaseRecordData(RecordData::YOUNG_TOTAL_ALIVE, youngAliveSize); 476 size_t promotedSize = heap_->GetPromotedSize(); 477 SetRecordData(RecordData::YOUNG_PROMOTE_SIZE, promotedSize); 478 IncreaseRecordData(RecordData::YOUNG_TOTAL_PROMOTE, promotedSize); 479 break; 480 } 481 case GCType::PARTIAL_OLD_GC: { 482 if (GetRecordData(RecordData::OLD_COUNT) == 0) { 483 SetRecordDuration(RecordDuration::OLD_MIN_PAUSE, duration); 484 SetRecordDuration(RecordDuration::OLD_MAX_PAUSE, duration); 485 } else { 486 SetRecordDuration(RecordDuration::OLD_MIN_PAUSE, 487 std::min(GetRecordDuration(RecordDuration::OLD_MIN_PAUSE), duration)); 488 SetRecordDuration(RecordDuration::OLD_MAX_PAUSE, 489 std::max(GetRecordDuration(RecordDuration::OLD_MAX_PAUSE), duration)); 490 } 491 IncreaseRecordData(RecordData::OLD_COUNT); 492 IncreaseRecordDuration(RecordDuration::OLD_TOTAL_PAUSE, duration); 493 size_t oldAliveSize = heap_->GetHeapObjectSize(); 494 SetRecordData(RecordData::OLD_ALIVE_SIZE, oldAliveSize); 495 IncreaseRecordData(RecordData::OLD_TOTAL_ALIVE, oldAliveSize); 496 break; 497 } 498 case GCType::COMPRESS_GC: { 499 if (GetRecordData(RecordData::COMPRESS_COUNT) == 0) { 500 SetRecordDuration(RecordDuration::COMPRESS_MIN_PAUSE, duration); 501 SetRecordDuration(RecordDuration::COMPRESS_MAX_PAUSE, duration); 502 } else { 503 SetRecordDuration(RecordDuration::COMPRESS_MIN_PAUSE, 504 std::min(GetRecordDuration(RecordDuration::COMPRESS_MIN_PAUSE), duration)); 505 SetRecordDuration(RecordDuration::COMPRESS_MAX_PAUSE, 506 std::max(GetRecordDuration(RecordDuration::COMPRESS_MAX_PAUSE), duration)); 507 } 508 IncreaseRecordData(RecordData::COMPRESS_COUNT); 509 IncreaseRecordDuration(RecordDuration::COMPRESS_TOTAL_PAUSE, duration); 510 size_t compressAliveSize = heap_->GetHeapObjectSize(); 511 SetRecordData(RecordData::COMPRESS_ALIVE_SIZE, compressAliveSize); 512 IncreaseRecordData(RecordData::COMPRESS_TOTAL_ALIVE, compressAliveSize); 513 break; 514 } 515 default: 516 break; 517 } 518 RecordGCSpeed(); 519 520 if (gcType_ == GCType::COMPRESS_GC && scopeDuration_[Scope::ScopeId::TotalGC] > longPauseTime_) { 521 IncreaseFullGCLongTimeCount(); 522 } 523 IncreaseTotalDuration(scopeDuration_[Scope::ScopeId::TotalGC]); 524 IncreaseAccumulatedFreeSize(GetRecordData(RecordData::START_OBJ_SIZE) - 525 GetRecordData(RecordData::END_OBJ_SIZE)); 526} 527 528void GCStats::RecordGCSpeed() 529{ 530 double survivalRate = GetAvgSurvivalRate(); 531 size_t clearNativeSpeed = GetRecordData(RecordData::START_NATIVE_POINTER_NUM) / 532 scopeDuration_[Scope::ScopeId::ClearNativeObject]; 533 534 if (gcType_ == GCType::PARTIAL_EDEN_GC) { 535 gcSpeed_[(uint8_t)SpeedData::MARK_SPEED] = 536 GetRecordData(RecordData::START_EDEN_OBJ_SIZE) / scopeDuration_[Scope::ScopeId::Mark]; 537 size_t evacuateSpeed = survivalRate * GetRecordData(RecordData::START_EDEN_OBJ_SIZE) / 538 scopeDuration_[Scope::ScopeId::EvacuateSpace]; 539 gcSpeed_[(uint8_t)SpeedData::EDEN_EVACUATE_SPACE_SPEED] = 540 (evacuateSpeed + gcSpeed_[(uint8_t)SpeedData::EDEN_EVACUATE_SPACE_SPEED]) / 2; // 2 means half 541 gcSpeed_[(uint8_t)SpeedData::EDEN_CLEAR_NATIVE_OBJ_SPEED] = 542 (clearNativeSpeed + gcSpeed_[(uint8_t)SpeedData::EDEN_CLEAR_NATIVE_OBJ_SPEED]) / 2; // 2 means half 543 size_t updateReferenceSpeed = GetRecordData(RecordData::START_OBJ_SIZE) / 544 scopeDuration_[Scope::ScopeId::UpdateReference]; 545 gcSpeed_[(uint8_t)SpeedData::EDEN_UPDATE_REFERENCE_SPEED] = 546 (updateReferenceSpeed + gcSpeed_[(uint8_t)SpeedData::EDEN_UPDATE_REFERENCE_SPEED]) / 2; // 2 means half 547 } else if (gcType_ == GCType::PARTIAL_YOUNG_GC) { 548 size_t objSize = 549 GetRecordData(RecordData::START_YOUNG_OBJ_SIZE) + GetRecordData(RecordData::START_EDEN_OBJ_SIZE); 550 gcSpeed_[(uint8_t)SpeedData::MARK_SPEED] = objSize / scopeDuration_[Scope::ScopeId::Mark]; 551 size_t evacuateSpeed = survivalRate * objSize / scopeDuration_[Scope::ScopeId::EvacuateSpace]; 552 gcSpeed_[(uint8_t)SpeedData::YOUNG_EVACUATE_SPACE_SPEED] = 553 (evacuateSpeed + gcSpeed_[(uint8_t)SpeedData::YOUNG_EVACUATE_SPACE_SPEED]) / 2; // 2 means half 554 gcSpeed_[(uint8_t)SpeedData::YOUNG_CLEAR_NATIVE_OBJ_SPEED] = 555 (clearNativeSpeed + gcSpeed_[(uint8_t)SpeedData::YOUNG_CLEAR_NATIVE_OBJ_SPEED]) / 2; // 2 means half 556 size_t updateReferenceSpeed = GetRecordData(RecordData::START_OBJ_SIZE) / 557 scopeDuration_[Scope::ScopeId::UpdateReference]; 558 gcSpeed_[(uint8_t)SpeedData::YOUNG_UPDATE_REFERENCE_SPEED] = 559 (updateReferenceSpeed + gcSpeed_[(uint8_t)SpeedData::YOUNG_UPDATE_REFERENCE_SPEED]) / 2; // 2 means half 560 } else if (gcType_ == GCType::PARTIAL_OLD_GC) { 561 gcSpeed_[(uint8_t)SpeedData::MARK_SPEED] = 562 GetRecordData(RecordData::START_OBJ_SIZE) / scopeDuration_[Scope::ScopeId::Mark]; 563 size_t sweepSpeed = GetRecordData(RecordData::START_OBJ_SIZE) / scopeDuration_[Scope::ScopeId::Sweep]; 564 gcSpeed_[(uint8_t)SpeedData::SWEEP_SPEED] = 565 (sweepSpeed + gcSpeed_[(uint8_t)SpeedData::SWEEP_SPEED]) / 2; // 2 means half 566 gcSpeed_[(uint8_t)SpeedData::OLD_CLEAR_NATIVE_OBJ_SPEED] = 567 (clearNativeSpeed + gcSpeed_[(uint8_t)SpeedData::OLD_CLEAR_NATIVE_OBJ_SPEED]) / 2; // 2 means half 568 569 size_t evacuateSpaceSpeed = (survivalRate * (GetRecordData(RecordData::START_YOUNG_OBJ_SIZE) + 570 GetRecordData(RecordData::START_EDEN_OBJ_SIZE)) + GetRecordData(RecordData::COLLECT_REGION_SET_SIZE)) / 571 scopeDuration_[Scope::ScopeId::EvacuateSpace]; 572 gcSpeed_[(uint8_t)SpeedData::OLD_EVACUATE_SPACE_SPEED] = 573 (evacuateSpaceSpeed + gcSpeed_[(uint8_t)SpeedData::OLD_EVACUATE_SPACE_SPEED]) / 2; // 2 means half 574 575 size_t updateReferenceSpeed = GetRecordData(RecordData::START_OBJ_SIZE) / 576 scopeDuration_[Scope::ScopeId::UpdateReference]; 577 gcSpeed_[(uint8_t)SpeedData::UPDATE_REFERENCE_SPEED] = 578 (updateReferenceSpeed + gcSpeed_[(uint8_t)SpeedData::UPDATE_REFERENCE_SPEED]) / 2; // 2 means half 579 } 580} 581 582GCType GCStats::GetGCType(TriggerGCType gcType) 583{ 584 if (heap_ && !heap_->IsReadyToConcurrentMark()) { 585 switch (heap_->GetMarkType()) { 586 case MarkType::MARK_EDEN: 587 return GCType::PARTIAL_EDEN_GC; 588 case MarkType::MARK_YOUNG: 589 return GCType::PARTIAL_YOUNG_GC; 590 case MarkType::MARK_FULL: 591 return GCType::PARTIAL_OLD_GC; 592 default: 593 return GCType::OTHER; 594 } 595 } 596 switch (gcType) { 597 case TriggerGCType::EDEN_GC: 598 return GCType::PARTIAL_EDEN_GC; 599 case TriggerGCType::YOUNG_GC: 600 return GCType::PARTIAL_YOUNG_GC; 601 case TriggerGCType::OLD_GC: 602 return GCType::PARTIAL_OLD_GC; 603 case TriggerGCType::FULL_GC: 604 return GCType::COMPRESS_GC; 605 case TriggerGCType::SHARED_GC: 606 return GCType::SHARED_GC; 607 case TriggerGCType::SHARED_FULL_GC: 608 return GCType::SHARED_FULL_GC; 609 default: 610 return GCType::OTHER; 611 } 612} 613 614void GCStats::InitializeRecordList() 615{ 616 for (float &duration : scopeDuration_) { 617 duration = 0.0f; 618 } 619 concurrentMark_ = false; 620} 621 622bool GCStats::CheckIfLongTimePause() 623{ 624 if (scopeDuration_[Scope::ScopeId::TotalGC] > longPauseTime_) { 625 LOG_GC(INFO) << "Has checked a long time gc"; 626 return true; 627 } 628 return false; 629} 630 631void SharedGCStats::PrintStatisticResult() 632{ 633 LOG_GC(INFO) << "/******************* SharedGCStats statistic: *******************/"; 634 PrintSharedGCSummaryStatistic(); 635 PrintGCMemoryStatistic(); 636} 637 638void SharedGCStats::PrintGCStatistic() 639{ 640 if (enableGCTracer_) { 641 LOG_GC(INFO) << " [ " << GetGCTypeName() << " ] " 642 << sizeToMB(recordData_[(uint8_t)RecordData::START_OBJ_SIZE]) << " (" 643 << sizeToMB(recordData_[(uint8_t)RecordData::START_COMMIT_SIZE]) << ") -> " 644 << sizeToMB(recordData_[(uint8_t)RecordData::END_OBJ_SIZE]) << " (" 645 << sizeToMB(recordData_[(uint8_t)RecordData::END_COMMIT_SIZE]) << ") MB, " 646 << scopeDuration_[Scope::ScopeId::TotalGC] << "ms, " << GCReasonToString(reason_); 647 PrintSharedGCDuration(); 648 PrintGCMemoryStatistic(); 649 PrintSharedGCSummaryStatistic(); 650 } 651 InitializeRecordList(); 652} 653 654void SharedGCStats::PrintSharedGCSummaryStatistic() 655{ 656 LOG_GC(INFO) << "/***************** GC summary statistic: *****************/"; 657 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("SharedGC occurs count") 658 << STATS_DATA_FORMAT(GetRecordData(RecordData::SHARED_COUNT)) << "\n" 659 << STATS_DESCRIPTION_FORMAT("SharedGC max pause:") 660 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::SHARED_MAX_PAUSE)) << "ms\n" 661 << STATS_DESCRIPTION_FORMAT("SharedGC min pause:") 662 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::SHARED_MIN_PAUSE)) << "ms\n" 663 << STATS_DESCRIPTION_FORMAT("SharedGC average pause:") 664 << STATS_DATA_FORMAT(GetRecordDuration(RecordDuration::SHARED_TOTAL_PAUSE) / 665 GetRecordData(RecordData::SHARED_COUNT)) << "ms\n" 666 << STATS_DESCRIPTION_FORMAT("SharedHeap average alive rate:") 667 << STATS_DATA_FORMAT(double(GetRecordData(RecordData::SHARED_TOTAL_ALIVE)) / 668 GetRecordData(RecordData::SHARED_TOTAL_COMMIT)); 669} 670 671void SharedGCStats::PrintGCMemoryStatistic() 672{ 673 NativeAreaAllocator *nativeAreaAllocator = sHeap_->GetNativeAreaAllocator(); 674 HeapRegionAllocator *heapRegionAllocator = sHeap_->GetHeapRegionAllocator(); 675 LOG_GC(INFO) << "/****************** GC Memory statistic: *****************/"; 676 LOG_GC(INFO) << "AllSpaces used:" 677 << STATS_DATA_FORMAT(sizeToKB(sHeap_->GetHeapObjectSize())) << "KB" 678 << " committed:" 679 << STATS_DATA_FORMAT(sizeToKB(sHeap_->GetCommittedSize())) << "KB\n" 680 << "SharedOldSpace used:" 681 << STATS_DATA_FORMAT(sizeToKB(sHeap_->GetOldSpace()->GetHeapObjectSize())) << "KB" 682 << " committed:" 683 << STATS_DATA_FORMAT(sizeToKB(sHeap_->GetOldSpace()->GetCommittedSize())) << "KB\n" 684 << "SharedNonMovableSpace used:" 685 << STATS_DATA_FORMAT(sizeToKB(sHeap_->GetNonMovableSpace()->GetHeapObjectSize())) << "KB" 686 << " committed:" 687 << STATS_DATA_FORMAT(sizeToKB(sHeap_->GetNonMovableSpace()->GetCommittedSize())) << "KB\n" 688 << "SharedHugeObjectSpace used:" 689 << STATS_DATA_FORMAT(sizeToKB(sHeap_->GetHugeObjectSpace()->GetHeapObjectSize())) << "KB" 690 << " committed:" 691 << STATS_DATA_FORMAT(sizeToKB(sHeap_->GetHugeObjectSpace()->GetCommittedSize())) << "KB\n" 692 << "SharedAppSpawnSpace used:" 693 << STATS_DATA_FORMAT(sizeToKB(sHeap_->GetAppSpawnSpace()->GetHeapObjectSize())) << "KB" 694 << " committed:" 695 << STATS_DATA_FORMAT(sizeToKB(sHeap_->GetAppSpawnSpace()->GetCommittedSize())) << "KB"; 696 697 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("Anno memory usage size:") 698 << STATS_DATA_FORMAT(sizeToMB(heapRegionAllocator->GetAnnoMemoryUsage())) << "MB\n" 699 << STATS_DESCRIPTION_FORMAT("Native memory usage size:") 700 << STATS_DATA_FORMAT(sizeToMB(nativeAreaAllocator->GetNativeMemoryUsage())) << "MB\n"; 701 702 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("Heap alive rate:") 703 << STATS_DATA_FORMAT(double(GetRecordData(RecordData::SHARED_ALIVE_SIZE)) / 704 GetRecordData(RecordData::SHARED_COMMIT_SIZE)); 705} 706 707void SharedGCStats::PrintSharedGCDuration() 708{ 709 LOG_GC(INFO) << STATS_DESCRIPTION_FORMAT("TotalGC:") 710 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::TotalGC]) << "ms\n" 711 << STATS_DESCRIPTION_FORMAT("Initialize:") 712 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Initialize]) << "ms\n" 713 << STATS_DESCRIPTION_FORMAT("Mark:") 714 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Mark]) << "ms\n" 715 << STATS_DESCRIPTION_FORMAT("Sweep:") 716 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Sweep]) << "ms\n" 717 << STATS_DESCRIPTION_FORMAT("Finish:") 718 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::Finish]) << "ms\n" 719 << STATS_DESCRIPTION_FORMAT("SuspendAll:") 720 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::SuspendAll]) << "ms\n" 721 << STATS_DESCRIPTION_FORMAT("ResumeAll:") 722 << STATS_DATA_FORMAT(scopeDuration_[Scope::ScopeId::ResumeAll]) << "ms"; 723} 724 725size_t SharedGCStats::GetAccumulatedAllocateSize() 726{ 727 return accumulatedFreeSize_ + sHeap_->GetHeapObjectSize(); 728} 729 730void SharedGCStats::RecordStatisticBeforeGC(TriggerGCType gcType, GCReason reason) 731{ 732 size_t commitSize = sHeap_->GetCommittedSize(); 733 SetRecordData(RecordData::START_OBJ_SIZE, sHeap_->GetHeapObjectSize()); 734 SetRecordData(RecordData::START_COMMIT_SIZE, commitSize); 735 SetRecordData(RecordData::SHARED_COMMIT_SIZE, commitSize); 736 IncreaseRecordData(RecordData::SHARED_TOTAL_COMMIT, commitSize); 737 gcType_ = GetGCType(gcType); 738 reason_ = reason; 739} 740 741void SharedGCStats::RecordStatisticAfterGC() 742{ 743 SetRecordData(RecordData::END_OBJ_SIZE, sHeap_->GetHeapObjectSize()); 744 SetRecordData(RecordData::END_COMMIT_SIZE, sHeap_->GetCommittedSize()); 745 746 float duration = scopeDuration_[Scope::ScopeId::TotalGC]; 747 if (GetRecordData(RecordData::SHARED_COUNT) == 0) { 748 SetRecordDuration(RecordDuration::SHARED_MIN_PAUSE, duration); 749 SetRecordDuration(RecordDuration::SHARED_MAX_PAUSE, duration); 750 } else { 751 SetRecordDuration(RecordDuration::SHARED_MIN_PAUSE, 752 std::min(GetRecordDuration(RecordDuration::SHARED_MIN_PAUSE), duration)); 753 SetRecordDuration(RecordDuration::SHARED_MAX_PAUSE, 754 std::max(GetRecordDuration(RecordDuration::SHARED_MAX_PAUSE), duration)); 755 } 756 IncreaseRecordData(RecordData::SHARED_COUNT); 757 IncreaseRecordDuration(RecordDuration::SHARED_TOTAL_PAUSE, duration); 758 size_t heapAliveSize = sHeap_->GetHeapObjectSize(); 759 SetRecordData(RecordData::SHARED_ALIVE_SIZE, heapAliveSize); 760 IncreaseRecordData(RecordData::SHARED_TOTAL_ALIVE, heapAliveSize); 761 762 IncreaseTotalDuration(scopeDuration_[Scope::ScopeId::TotalGC]); 763 IncreaseAccumulatedFreeSize(GetRecordData(RecordData::START_OBJ_SIZE) - 764 GetRecordData(RecordData::END_OBJ_SIZE)); 765} 766} // namespace panda::ecmascript 767