Skip to content
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

Potential memory leak #139

Open
DavidBoike opened this issue Dec 7, 2015 · 2 comments
Open

Potential memory leak #139

DavidBoike opened this issue Dec 7, 2015 · 2 comments

Comments

@DavidBoike
Copy link
Member

DavidBoike commented Dec 7, 2015

Pretty simple repro, using NServiceBus 5.2.9 and NServiceBus.NHibernate 6.2.3 on .NET 4.6:

using System;
using System.Diagnostics;
using System.Threading;
using NServiceBus;
using NServiceBus.Persistence;
using NServiceBus.Config;
using NServiceBus.Config.ConfigurationSource;
using NServiceBus.Logging;

namespace TestForLeak3
{
    class Program
    {
        static void Main(string[] args)
        {
            LogManager.Use<DefaultFactory>().Level(LogLevel.Error);

            for (int run = 0; run < 5; run++)
            {
                Console.WriteLine($"Run {run+1}/5");
                for (int i = 0; i < 10; i++)
                {
                    using (var bus = GetBus())
                    {
                        Console.WriteLine($"  Bus {i + 1}/10");
                    }
                }
                Console.WriteLine("  Waiting 5s");
                Thread.Sleep(5000);
                Console.WriteLine("  Running GC");
                GC.Collect();
                Console.WriteLine("  GC done, waiting 5s, take snapshot now!");
                Thread.Sleep(5000);
            }
            Debugger.Break();
            Console.ReadLine();
        }

        private static IBus GetBus()
        {
            BusConfiguration cfg = new BusConfiguration();

            cfg.UseSerialization<XmlSerializer>();
            cfg.UsePersistence<NHibernatePersistence>()
                .ConnectionString(@"Data Source=.\SQLEXPRESS;Initial Catalog=FindMemLeak;Trusted_Connection=true;");
            cfg.EndpointName("MemLeakTest3");
            cfg.EnableInstallers();

            return Bus.Create(cfg).Start();
        }
    }

    class CustomConfig : IProvideConfiguration<MessageForwardingInCaseOfFaultConfig>,
            IProvideConfiguration<AuditConfig>
    {
        AuditConfig IProvideConfiguration<AuditConfig>.GetConfiguration()
        {
            return new AuditConfig
            {
                QueueName = "audit"
            };
        }

        public MessageForwardingInCaseOfFaultConfig GetConfiguration()
        {
            return new MessageForwardingInCaseOfFaultConfig
            {
                ErrorQueue = "error"
            };
        }
    }
}

Taking snapshots in VS2015 Diagnostic Tools yields a fairly predictable increase in heap objects with each run:

image

Although, this may be fairly low priority since it assumes bus instances are going to be created and destroyed constantly.

But, compare this to if you switch to InMemory persistence:

image

The sheer difference in scale may make this something to look at.

@SzymonPobiega
Copy link
Member

Looking at the code, at least in V6 we don't ever dispose ISessionFactory. I suspect that it was the same in V5 and that this is the root cause of the leak. @Particular/nhibernate-persistence-maintainers should we prioritize this?

@DavidBoike
Copy link
Member Author

I forgot I had opened this.

It only matters if you're continuously creating and destroying endpoints, which you really shouldn't do, right?

To me that gives it pretty low priority, the kind of change you'd roll into a minor you were going to release anyway if you had a free moment.

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

No branches or pull requests

3 participants