-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Add a general-purpose property bag to Compilation #5542
Comments
I don't know if we have an existing "property bag" type we can use or if there's an example of an API we like. I expect the implementation is a |
Please keep DotNetAnalyzers/StyleCopAnalyzers#1304 in mind as you implement this. |
👍 A purpose-built, efficient way to do this would be fantastic. |
Isn't one of the benefits of |
I have just the right API for this. I will explain next week. |
@axel-habermaier You're right. "memory leak" mischaracterizes the issue. Although, CWT doesn't scavenge old entries (call DependentHandle.Free) unless there is churn (add or remove) and who ever calls @sharwell Can you expand on what I should look out for? I looked at the issue you mentioned. I a @gafter looking forward the explanation! |
The GC pressure I'm referring to comes from the DependentHandle allocations. DependentHandles in the GC are stored It's an additional table that the GC has to scan for references. It's pretty much a linear scan through that unordered table to mark additional rooted objects ("If primary is alive, then mark secondary as alive"). I've never actually seen this show up in profiles, but it's like a 'peanut butter' cost on every GC. CWT has its place for adding sparse annotations to an object graph. However, in Roslyn, Compilation is such an obvious target for annotation - especially in analyzers - that it makes sense to add this property bag. The lifetime is obvious and no dependent handles are required. |
@pharring Accessing the CWT is very expensive in concurrent code. We saw significant gains by ensuring the CWT is only accessed once per analyzer per compilation. |
@sharwell Thanks for the explanation. Yes, the guts of CWT are protected by a single sync object which leads to lock contention in highly concurrent code. That's another reason to avoid it. We will use |
Please consider using strongly-typed accessors around the bag to avoid obvious cast errors. One pattern I often use for this case:
Usage:
All accesses are strongly typed, you don't have to figure out a good unique key, and you can keep that key private. |
@MrJul thanks. I agree that having generic helper methods (extension methods on Compilation) would help to avoid casts in caller code. But I don't think that it's necessary to introduce The ability to keep the keys private is a requirement, but I think that can be enforced in the callers - or not if they choose to share their well-known keys with others. If they want a private key, then, as you've shown, Therefore, I think Still waiting to hear @gafter's suggestion. |
Please see #5708 as a draft of the approach I'm suggesting. I need help with naming. |
@tmat asked for a list of use cases: And of course, the one that @sharwell mentioned above: DotNetAnalyzers/StyleCopAnalyzers#1304 |
I sense the prevailing wind is "Won't Fix". Is that right? |
We have many places in our code base where we have
ConditionalWeakTable<Compilation, ...>
Each one makes me cringe because of the potential memory leaks and additional GC pressure.
What people really want is to tie arbitrary data to the lifetime of a compilation.
We should instead just add general purpose property bag to the Compilation object and recommend that people use that instead of creating new CWTs.
The text was updated successfully, but these errors were encountered: