You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm trying to troubleshoot some memory issues. When using dotMemory for a process that has been running for awhile, we noticed the _registrations of type HashRegistry holding on to a lot of memory. When I dig into it further, it appears that BuilderContext has an Existing property from prior resolutions? Which seems odd since the registrations in question are Transient. Not sure why it would be hanging on to these references which I then assume are not getting disposed.
I could be way off and just trying to understand what's happening. Any help pointing me in the right direction if I'm doing something wrong. We didn't seem to notice any of this until we upgraded to 5.7.3 awhile ago.
I do see that this was added fairly recently. I've forked and am troubleshooting myself so I can try and figure out what's happening. Not exactly sure what other info to provide.
Just for more info, we upgrade to the latest and we are still noticing high memory usage.
I have tried to use dotMemory Unit to try and replicate in a test but cannot. I'm still trying to dig through my latest dotMemory profile to try and figure out why container is holding so much memory. As mentioned before the _registrations is what's really large.
Here's a couple screenshots of dotMemory results.
Here's an individual entry.
What's interesting here is the existing entry has a reference to AdminQueryContext which is registered as Transient. Why is it hanging on to this reference?
Also the above is the top level instance of the container in the application, I believe. I don't understand the unity internals enough however to know why this instance (parent) would have references when nothing is resolved from the root but rather is done from a child container. If this is the case, this makes sense that these instances are being held on to because the parent container is never disposed. So even if a child container is disposed, these objects will hang around because they are also associated to the parent, which is never disposed.
The parent _registrations is holding all 'factories' for all known types unless it is overridden in child container. Once constructed it becomes available to all child containers and will resolve from existing, already compiled pipeline in the root._registrations. This way it will not require to be built every time new child container is created. The behavior is by design.
As with everything in life you have to pay the price. Either compact and slow or large and fast. Unity is taking later approach.
I think it could be optimized and made better. After 5.7.3 release memory footprint has increased but performance jumped tenfold.
The numbers shown in your pics are rather high but it could be totally legit if these all registrations. I really need the test case to diagnose this issue. Perhaps small app I could run?
I'll try and create a small app that does similar types of registrations and profile it myself.
Not to beat a dead horse to my previous comment, but if the parent container is holding references to resolved objects that resolved in a child container, they are never going to get disposed.
Am I interpreting it wrong from the screenshot above? I realize you mentioned it's all the factories, but that's BuildContext itself seems to be holding references?
If you have registered both a mapping from an interface to a class and just the class resolving the interface retains all resolved instances in the chain to that interface. Can we reopen this issue or do you prefer that I create a new one?
The following example will retain the instances of both Bar and Foo.
Activity
ENikS commentedon May 1, 2018
v5.7.3 intorduced big changes related to performance optimizations. Perhaps it created reference that holds these objects in memory.
I would be happy to help if you could supply more info.
dcomartin commentedon May 1, 2018
I do see that this was added fairly recently. I've forked and am troubleshooting myself so I can try and figure out what's happening. Not exactly sure what other info to provide.
ENikS commentedon May 2, 2018
Could you create a test case demonstrating the problem?
dcomartin commentedon May 2, 2018
Ya I'm trying to work through creating a test(s) with dotMemory Unit to see if I can replicate what I'm experiencing.
dcomartin commentedon May 10, 2018
Just for more info, we upgrade to the latest and we are still noticing high memory usage.
I have tried to use dotMemory Unit to try and replicate in a test but cannot. I'm still trying to dig through my latest dotMemory profile to try and figure out why container is holding so much memory. As mentioned before the
_registrationsis what's really large.Here's a couple screenshots of dotMemory results.
Here's an individual entry.
What's interesting here is the existing entry has a reference to
AdminQueryContextwhich is registered as Transient. Why is it hanging on to this reference?dcomartin commentedon May 10, 2018
Also the above is the top level instance of the container in the application, I believe. I don't understand the unity internals enough however to know why this instance (parent) would have references when nothing is resolved from the root but rather is done from a child container. If this is the case, this makes sense that these instances are being held on to because the parent container is never disposed. So even if a child container is disposed, these objects will hang around because they are also associated to the parent, which is never disposed.
ENikS commentedon May 10, 2018
The parent _registrations is holding all 'factories' for all known types unless it is overridden in child container. Once constructed it becomes available to all child containers and will resolve from existing, already compiled pipeline in the root._registrations. This way it will not require to be built every time new child container is created. The behavior is by design.
As with everything in life you have to pay the price. Either compact and slow or large and fast. Unity is taking later approach.
I think it could be optimized and made better. After 5.7.3 release memory footprint has increased but performance jumped tenfold.
The numbers shown in your pics are rather high but it could be totally legit if these all registrations. I really need the test case to diagnose this issue. Perhaps small app I could run?
dcomartin commentedon May 10, 2018
I'll try and create a small app that does similar types of registrations and profile it myself.
Not to beat a dead horse to my previous comment, but if the parent container is holding references to resolved objects that resolved in a child container, they are never going to get disposed.
Am I interpreting it wrong from the screenshot above? I realize you mentioned it's all the factories, but that's
BuildContextitself seems to be holding references?ENikS commentedon May 10, 2018
BuildContextshould not be referenced beyond the resolution request. If it is held longer, it is a bug.dcomartin commentedon May 10, 2018
In the meantime, I'm downgrading to the 5.5.5 which is what we were using prior to 5.7.3.
ENikS commentedon May 11, 2018
I am not seeing this behavior in my tests. Are you doing something special in your app?
dcomartin commentedon May 14, 2018
Nothing special that I'm aware of.
After we downgraded to 5.5.5, without any other changes, we are seeing a pretty drastic change in memory usage.
When running dotMemory since the downgrade and comparing snapshots, here's the difference.
5.5.5

5.8.6
ENikS commentedon Aug 13, 2018
It's been 2 month. No test case has been provided so I am assuming this is no longer an issue.
appel1 commentedon Oct 25, 2018
If you have registered both a mapping from an interface to a class and just the class resolving the interface retains all resolved instances in the chain to that interface. Can we reopen this issue or do you prefer that I create a new one?
The following example will retain the instances of both Bar and Foo.
ENikS commentedon Dec 4, 2018
Fixed in ee085a2
prashanthmp7 commentedon Jan 28, 2020
Hi,
I am facing the exact issue. We are using the latest version as of today that is 5.11.1. Looks like the issue still persists.