Skip to content

Fix for solving lock contention issue in GC statics scanning. #32795

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

Merged
merged 2 commits into from
Mar 6, 2020

Conversation

PeterSolMS
Copy link
Contributor

I believe this is a better solution for GC statics scanning.

Instead of walking through the module list and scanning the statics for each module, walk the buckets in the large heap handle table where the statics are stored. This list is only changed in cooperative mode, so it should be safe to walk during GC suspensions.

@jkotas
Copy link
Member

jkotas commented Feb 25, 2020

This looks good to me as an incremental improvement.

It still unfortunate that this is done during STW pause. I believe we should be taking every opportunity to move work from STW pauses to background.

@PeterSolMS
Copy link
Contributor Author

Well, what we do during STW pause is essentially snapshotting the object pointers stored in the statics, we don't explore the object graph yet.

I think it's possible in principle to do the scanning while the program is running, this will likely need some care so we don't run into tricky race conditions.

@Maoni0
Copy link
Member

Maoni0 commented Feb 25, 2020

great! this is a much better solution.

re switching orders in GCToEEInterface::GcScanRoots - I think in general this should be better except for the one scenario I pointed out (where a stack var holds onto the object array).

@Maoni0
Copy link
Member

Maoni0 commented Feb 25, 2020

approved but I know Peter is working on a test to verify so there may (but unlikely) be some changes coming from that.

@VSadov
Copy link
Member

VSadov commented Feb 25, 2020

I like this fix more than the previous one too.

@VSadov
Copy link
Member

VSadov commented Feb 25, 2020

Re: doing the scan outside of STW. One way to do that could be storing the statics in managed arrays, - similar to what we do with collectible assemblies. Then scanning happens naturally.
That would be a feature work beyond the scope of a bug fix though.

@jkotas
Copy link
Member

jkotas commented Feb 25, 2020

The statics are stored in managed arrays. This extra code frontloads scanning of these managed arrays with statics. It is not required for correctness - if it was deleted, everything would still correctly, just the timing would be different.

@VSadov
Copy link
Member

VSadov commented Feb 25, 2020

The code mentions that this is not needed for collectible assemblies because they are stored in managed arrays, so I assumed that regular statics are not.

@VSadov
Copy link
Member

VSadov commented Feb 25, 2020

In such case, perhaps enumerating just the arrays would be sufficient? - I.E. no need to dig into elements?

@jkotas
Copy link
Member

jkotas commented Feb 26, 2020

You can make a similar argument for why this front-loading is beneficial at all. It is why it would be useful to have a micro-benchmark to demonstrate it. Then we can at least somewhat reason about the impact of different tweaks.

@VSadov
Copy link
Member

VSadov commented Feb 26, 2020

Right. Enumerating just the containing arrays is basically the same as enumerating handles and we do that a few lines later.

My concern was that if multiple threads will start fight for every static variable, there could be some issues with false sharing. If you have N threads and K statics, it seems it would result in N*K accesses to the same data and in a worst case nearly all will be cache misses.

@PeterSolMS
Copy link
Contributor Author

I wrote the micro-benchmark that Jan and Maoni suggested. Result is that there is significant benefit to the front-loading, but the handle table scanning is still the long pole in many cases. This is probably because if the thread doing the handle table scanning gets first to the array containing the statics, it will greedily mark the contained objects before actually tracing the contained object graphs. The other threads will then conclude there's nothing to do for them. Switching the order of handle table scanning and draining the mark list fixed this, but that is for a later checkin.

@jkotas
Copy link
Member

jkotas commented Mar 5, 2020

Is this good to merge?

@Maoni0
Copy link
Member

Maoni0 commented Mar 5, 2020

I think so unless @PeterSolMS has objections?

@jkotas jkotas merged commit cfb1a7e into dotnet:master Mar 6, 2020
@Maoni0 Maoni0 mentioned this pull request Sep 8, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants