Description
Our applications uses a lot of COM-like interfaces to communicate with C++ code. And I found that the GC became much slower when many of them created. To me it looks like even Gen 0 is affected.
I've attached small project that demonstrate the problem. Demo.zip
It creates 1.5M RCW's and then simulates the Newtonsoft Deserialize function by creating strings and arrays. With 1.5M RCW's it takes more than 100 seconds on my PC. If you comment RCW creating (the first for-loop), then it takes from 2 to 2.5 seconds. Just in case creating RCW's takes only 1 second.
If you add following code:
public class ClientApiAgile : IClientApiAgile { }
and replace the body of the first for-loop to this:
rcws.Add(new ClientApiAgile());
it also takes 2.5 seconds, so number of objects is not a problem.
STR:
- Open the C++ project from
Cpp directory, switch to the Release configuration and compile project. I used VS 2022 to compile it. It has very basic COM-like interface.
- Open the C# project from the
DotNet\App directory, switch to the Release configuration and run it without debugger.
Configuration
.NET 8, .NET 10.
Windows 11, x64
Regression?
I don't think so.
Data
- It takes 100 seconds to execute the application with 1.5M of RCW's
- When the first for loop is commented, it takes 2.5 seconds to execute the simulation.
- When the first loop creates 1.5M of the regular .NET objects, it takes 2.5 seconds to execute the simulation.
Analysis
It looks like the GC calls GCToEEInterface::AfterGcScanRoots, that function calls AppDomain::DetachRCWs and that function calls DetachWrappersWorker where the most of the time is spent.
I understand that this code must run but perhaps it can execute less often. Or perhaps that code can execute faster.
We are porting some native code to C# but some bits and pieces are still on the native C++ side. We could have up to 5M of RCW's and I afraid that our customers will have micro-freezes when use our application.
From what I see it looks like there is no workaround. Probably the new COM that uses source generator can help, but we are using thousands interfaces and converting everything to the new COM will require a lot of work. Plus I think it also uses RCW's internally.
Any help or workaround will be greatly appreciated!
Description
Our applications uses a lot of COM-like interfaces to communicate with C++ code. And I found that the GC became much slower when many of them created. To me it looks like even Gen 0 is affected.
I've attached small project that demonstrate the problem. Demo.zip
It creates 1.5M RCW's and then simulates the Newtonsoft Deserialize function by creating strings and arrays. With 1.5M RCW's it takes more than 100 seconds on my PC. If you comment RCW creating (the first for-loop), then it takes from 2 to 2.5 seconds. Just in case creating RCW's takes only 1 second.
If you add following code:
and replace the body of the first for-loop to this:
it also takes 2.5 seconds, so number of objects is not a problem.
STR:
Cppdirectory, switch to the Release configuration and compile project. I used VS 2022 to compile it. It has very basic COM-like interface.DotNet\Appdirectory, switch to the Release configuration and run it without debugger.Configuration
.NET 8, .NET 10.
Windows 11, x64
Regression?
I don't think so.
Data
Analysis
It looks like the GC calls
GCToEEInterface::AfterGcScanRoots, that function callsAppDomain::DetachRCWsand that function callsDetachWrappersWorkerwhere the most of the time is spent.I understand that this code must run but perhaps it can execute less often. Or perhaps that code can execute faster.
We are porting some native code to C# but some bits and pieces are still on the native C++ side. We could have up to 5M of RCW's and I afraid that our customers will have micro-freezes when use our application.
From what I see it looks like there is no workaround. Probably the new COM that uses source generator can help, but we are using thousands interfaces and converting everything to the new COM will require a lot of work. Plus I think it also uses RCW's internally.
Any help or workaround will be greatly appreciated!