fixed memory leak PCLStatsShutdown event · GameTechDev/PresentMon@8e303cc (original) (raw)

`@@ -2365,8 +2365,8 @@ void PMTraceConsumer::CompletePresent(std::shared_ptr const& p)

`

2365

2365

`static_cast(appFrameId - it->second.FrameId) >= 10) {

`

2366

2366

`// Remove the app frame data if the app frame id is too old

`

2367

2367

` it = mAppTimingDataByAppFrameId.erase(it); // Erase and move to the next element

`

2368

``

`-

} else if (appFrameId == 0 && it->second.ProcessId == processId &&

`

2369

``

`-

it->second.AssignedToPresent == false && it->second.AppPresentStartTime != 0 &&

`

``

2368

`+

} else if (appFrameId == 0 && it->second.ProcessId == processId &&

`

``

2369

`+

it->second.AssignedToPresent == false && it->second.AppPresentStartTime != 0 &&

`

2370

2370

` presentStartTime >= it->second.AppPresentStartTime &&

`

2371

2371

` presentStartTime - it->second.AppPresentStartTime >= mDeferralTimeLimit) {

`

2372

2372

`// Remove app frame data if the app present start time is too old

`

`@@ -2376,6 +2376,47 @@ void PMTraceConsumer::CompletePresent(std::shared_ptr const& p)

`

2376

2376

` ++it; // Move to the next element

`

2377

2377

` }

`

2378

2378

` }

`

``

2379

+

``

2380

`+

// Prune out old PC Latency timing data to prevent memory leaks.

`

``

2381

`+

// This is critical because PCL data accumulates for every frame and the

`

``

2382

`+

// PCLStatsShutdown event (the only other cleanup mechanism) is app-controlled.

`

``

2383

`+

if (mTrackPcLatency) {

`

``

2384

`+

auto pclFrameId = present->PclFrameId;

`

``

2385

`+

for (auto it = mPclTimingDataByPclFrameId.begin(); it != mPclTimingDataByPclFrameId.end();) {

`

``

2386

`+

if (it->first.second == processId) {

`

``

2387

`+

// For entries from this process:

`

``

2388

`+

// 1. Remove if assigned and frame ID is too old (10+ frames behind)

`

``

2389

`+

// 2. Remove if timestamp is too old (stale data - assigned or not)

`

``

2390

`+

bool shouldRemove = false;

`

``

2391

+

``

2392

`+

// Get the best available timestamp for this entry

`

``

2393

`+

uint64_t timingValue = mUsingOutOfBoundPresentStart

`

``

2394

`+

? it->second.PclOutOfBandPresentStartTime

`

``

2395

`+

: it->second.PclPresentStartTime;

`

``

2396

`+

if (timingValue == 0) {

`

``

2397

`+

timingValue = it->second.PclSimStartTime;

`

``

2398

`+

}

`

``

2399

+

``

2400

`+

if (pclFrameId != 0 && it->second.AssignedToPresent &&

`

``

2401

`+

static_cast(pclFrameId - it->second.FrameId) >= 10) {

`

``

2402

`+

// Remove assigned PCL data if frame id is too old

`

``

2403

`+

shouldRemove = true;

`

``

2404

`+

} else if (timingValue != 0 && presentStartTime >= timingValue &&

`

``

2405

`+

presentStartTime - timingValue >= mDeferralTimeLimit) {

`

``

2406

`+

// Remove PCL data (assigned or not) if timestamp is too old

`

``

2407

`+

shouldRemove = true;

`

``

2408

`+

}

`

``

2409

+

``

2410

`+

if (shouldRemove) {

`

``

2411

`+

it = mPclTimingDataByPclFrameId.erase(it);

`

``

2412

`+

} else {

`

``

2413

`+

++it;

`

``

2414

`+

}

`

``

2415

`+

} else {

`

``

2416

`+

++it;

`

``

2417

`+

}

`

``

2418

`+

}

`

``

2419

`+

}

`

2379

2420

`}

`

2380

2421

``

2381

2422

`void PMTraceConsumer::UpdateReadyCount(bool useLock)

`

`@@ -2708,6 +2749,16 @@ void PMTraceConsumer::HandleProcessEvent(EVENT_RECORD* pEventRecord)

`

2708

2749

` event.ProcessId = desc[0].GetData();

`

2709

2750

` event.IsStartEvent = false;

`

2710

2751

``

``

2752

`+

// Clean up PC Latency tracking data for this process to prevent memory leaks.

`

``

2753

`+

// This is necessary because PCLStatsShutdown events are application-controlled

`

``

2754

`+

// and may not be sent if the app crashes or terminates abnormally.

`

``

2755

`+

if (mTrackPcLatency) {

`

``

2756

`+

std::erase_if(mPclTimingDataByPclFrameId, [&event](const auto& p) {

`

``

2757

`+

return p.first.second == event.ProcessId;

`

``

2758

`+

});

`

``

2759

`+

mLatestPingTimestampByProcessId.erase(event.ProcessId);

`

``

2760

`+

}

`

``

2761

+

2711

2762

`break;

`

2712

2763

` }

`

2713

2764

`default:

`

`@@ -2734,6 +2785,14 @@ void PMTraceConsumer::HandleProcessEvent(EVENT_RECORD* pEventRecord)

`

2734

2785

`mMetadata.GetEventData(pEventRecord, desc, _countof(desc));

`

2735

2786

` event.ProcessId = desc[0].GetData();

`

2736

2787

` event.IsStartEvent = false;

`

``

2788

+

``

2789

`+

// Clean up PC Latency tracking data for this process to prevent memory leaks.

`

``

2790

`+

if (mTrackPcLatency) {

`

``

2791

`+

std::erase_if(mPclTimingDataByPclFrameId, [&event](const auto& p) {

`

``

2792

`+

return p.first.second == event.ProcessId;

`

``

2793

`+

});

`

``

2794

`+

mLatestPingTimestampByProcessId.erase(event.ProcessId);

`

``

2795

`+

}

`

2737

2796

` } else {

`

2738

2797

`return;

`

2739

2798

` }

`