Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API Proposal]: Exposing the total paused duration in GC. #66036

Closed
cshung opened this issue Mar 1, 2022 · 9 comments · Fixed by #68835
Closed

[API Proposal]: Exposing the total paused duration in GC. #66036

cshung opened this issue Mar 1, 2022 · 9 comments · Fixed by #68835
Labels
api-approved API was approved in API review, it can be implemented api-suggestion Early API idea and discussion, it is NOT ready for implementation area-GC-coreclr
Milestone

Comments

@cshung
Copy link
Member

cshung commented Mar 1, 2022

Background and motivation

Today we have already exposed the total paused time as a percentage of the process time on the GetGCMemoryInfo API.

In particular, through the PauseTimePercentage field on the GCMemoryInfo struct.

This is useful, but what if I only want to numerator (i.e. the total amount of time paused in GC since the beginning of the process?). There is no way to get that value for now.

API Proposal

I am proposing to add an API on System.GC as follow:

TimeSpan System.GC.GetTotalPauseDuration()

This will return the total paused duration in the GC

API Usage

...
TimeSpan start = System.GC.GetTotalPauseDuration();
// ... Perform some work ...
TimeSpan end= System.GC.GetTotalPauseDuration();
Console.WriteLine(end - start + " was spent pausing in GC");
...

Alternative Designs

We have considered the alternative to add a field on the GetGCMemoryInfo API, this will also work, but if the only thing we wanted is just the total pause time, that API will carry a larger overhead than necessary.

Risks

No response

@cshung cshung added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Mar 1, 2022
@dotnet-issue-labeler dotnet-issue-labeler bot added area-GC-coreclr untriaged New issue has not been triaged by the area owner labels Mar 1, 2022
@ghost
Copy link

ghost commented Mar 1, 2022

Tagging subscribers to this area: @dotnet/gc
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

Today we have already exposed the total paused time as a percentage of the process time on the GetGCMemoryInfo API.

In particular, through the PauseTimePercentage field on the GCMemoryInfo struct.

This is useful, but what if I only want to numerator (i.e. the total amount of time paused in GC since the beginning of the process?). There is no way to get that value for now.

API Proposal

I am proposing to add an API on System.GC as follow:

TimeSpan System.GC.GetTotalPauseDuration()

This will return the total paused duration in the GC

API Usage

...
TimeSpan start = System.GC.GetTotalPauseDuration();
// ... Perform some work ...
TimeSpan end= System.GC.GetTotalPauseDuration();
Console.WriteLine(end - start + " was spent pausing in GC");
...

Alternative Designs

We have considered the alternative to add a field on the GetGCMemoryInfo API, this will also work, but if the only thing we wanted is just the total pause time, that API will carry a larger overhead than necessary.

Risks

No response

Author: cshung
Assignees: -
Labels:

api-suggestion, area-GC-coreclr, untriaged

Milestone: -

@cshung
Copy link
Member Author

cshung commented Mar 3, 2022

@timmydo Hopefully, this can help with your performance analysis needs.

@timmydo
Copy link

timmydo commented Mar 3, 2022

Thanks! + @sudeepagarwal

@timmydo
Copy link

timmydo commented Mar 30, 2022

this looks good to me. can't wait to try it out.

@cshung cshung added the api-ready-for-review API is ready for review, it is NOT ready for implementation label Apr 13, 2022
@cshung cshung added this to the 7.0.0 milestone Apr 13, 2022
@terrajobst
Copy link
Member

How is System.GC.GetTotalPauseDuration() related to GCMemoryInfo.PauseDurations? Is the primary goal to make this cheaper? If so, does this mean we're going to expose more and more data from GCMemoryInfo?

@cshung
Copy link
Member Author

cshung commented Apr 14, 2022

GCMemoryInfo.PauseDurations are (*) the time spent pausing in the GC during the last GC.

GCMemoryInfo.PauseDurations are (*) the time spent pausing in the GC during the last GC.

System.GC.GetTotalPauseDuration() is the total time spent suspended in the GC since the process starts.

(*) Plurals - because for background GC, we pause for a few disjoint brief periods.

@terrajobst
Copy link
Member

So in other words, GetTotalPauseDuration() is <= Sum(GCMemoryInfo.PauseDurations) because those could have happened concurrently?

@Maoni0
Copy link
Member

Maoni0 commented Apr 15, 2022

no, GetTotalPauseDuration() is always >= Sum(GCMemoryInfo.PauseDurations)

GCMemoryInfo.PauseDurations are durations for when the GC is NOT running concurrently, in other words, these are the durations that GC did work while the managed threads are paused. they are never for when GC is doing work concurrently. whether there's one or multiple durations per GC is not really relevant here (yes, BGCs will report 2 durations while blocking GCs will report one per GC but that's an implementation detail).

the reason why GetTotalPauseDuration() is always >= Sum(GCMemoryInfo.PauseDurations) is because GetGCMemoryInfo is a sampling API. so assuming you called it early enough and frequent enough to catch every single GC that happened, it means what you get from GetTotalPauseDuration will be exactly the same as the sum of what you get from every GC's PauseDurations. but if you don't sample frequent enough to get every single GC, what you get from GetTotalPauseDuration will be > Sum(GCMemoryInfo.PauseDurations).

and yes, the reason why we wanted to provide the accumulated pause duration in its own API is to make it cheaper. this does not mean we will want to expose the accumulated version of all the data you get right now in GCMemoryInfo - most data simply does not make sense to be presented in an accumulated form. there are a couple of things that may make some sense to expose as accumulated, but no strong justification.

@terrajobst
Copy link
Member

terrajobst commented Apr 21, 2022

Video

  • Looks good as proposed
namespace System;

public partial class GC
{
    public static TimeSpan GetTotalPauseDuration();
}

@terrajobst terrajobst added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for review, it is NOT ready for implementation labels Apr 21, 2022
@jeffschwMSFT jeffschwMSFT removed the untriaged New issue has not been triaged by the area owner label Apr 25, 2022
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label May 3, 2022
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label May 20, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Jun 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented api-suggestion Early API idea and discussion, it is NOT ready for implementation area-GC-coreclr
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants