Skip to content

Memory Usage? #86

Closed
Closed

Description

@dcomartin

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.

public object Existing { get; set; }

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.

Activity

  1. ENikS commented on May 1, 2018

    @ENikS
    Contributor

    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.

  2. dcomartin commented on May 1, 2018

    @dcomartin
    Author

    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.

  3. ENikS commented on May 2, 2018

    @ENikS
    Contributor

    Could you create a test case demonstrating the problem?

  4. dcomartin commented on May 2, 2018

    @dcomartin
    Author

    Ya I'm trying to work through creating a test(s) with dotMemory Unit to see if I can replicate what I'm experiencing.

  5. dcomartin commented on May 10, 2018

    @dcomartin
    Author

    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.

    capture

    Here's an individual entry.

    capture2

    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?

  6. dcomartin commented on May 10, 2018

    @dcomartin
    Author

    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.

  7. ENikS commented on May 10, 2018

    @ENikS
    Contributor

    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?

  8. dcomartin commented on May 10, 2018

    @dcomartin
    Author

    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?

  9. ENikS commented on May 10, 2018

    @ENikS
    Contributor

    BuildContext should not be referenced beyond the resolution request. If it is held longer, it is a bug.

  10. dcomartin commented on May 10, 2018

    @dcomartin
    Author

    In the meantime, I'm downgrading to the 5.5.5 which is what we were using prior to 5.7.3.

  11. ENikS commented on May 11, 2018

    @ENikS
    Contributor

    I am not seeing this behavior in my tests. Are you doing something special in your app?

  12. dcomartin commented on May 14, 2018

    @dcomartin
    Author

    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
    capture

    5.8.6

    capture2

  13. ENikS commented on Aug 13, 2018

    @ENikS
    Contributor

    It's been 2 month. No test case has been provided so I am assuming this is no longer an issue.

  14. appel1 commented on Oct 25, 2018

    @appel1

    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.

        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
    
                m_container.RegisterType<Foo>();
                m_container.RegisterType<IFoo, Foo>();
    
                m_container.Resolve<Bar>();
            }
    
            private readonly IUnityContainer m_container = new UnityContainer();
        }
    
        public interface IFoo
        {
        }
    
        public class Foo : IFoo
        {
        }
    
        public class Bar
        {
            public Bar(IFoo foo)
            {
            }
        }
  15. reopened this on Oct 29, 2018
  16. ENikS commented on Dec 4, 2018

    @ENikS
    Contributor

    Fixed in ee085a2

  17. prashanthmp7 commented on Jan 28, 2020

    @prashanthmp7

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions