We are having a problem with a memory leak between our MVC3 web application and our WCF data layer service.
I believe the problem is from the WCF side, although cannot track it down. I've searched the web and these forums, but have not been able to find the cause. Any help would be much appreciated!
So - the initial symptom was the size of the w3wp process associated with the backend growing constantly. We can see it grows by a variable amount (order of magnitude 100kb) every time a simple call is made from the web app that calls a service.
Running Jetbrains memory profile against the app we can see that
System.ServiceModel.Channels.TransmissionStrategy.SlidingWindow
is by far and away the culprit. At app startup there are 4 objects instantiated with a tiny amount of memory (6.4% of total), after mild use it rises to > 200 objects, ~50% of total. Continued use drives this towards 100%. I've never heard of this before, but some googling indicates that it is used (amongst other things) in the transmission of data to and from the WCF layer.
My current line of thought is that processes are being created, but never released correctly. Our services are created from Castle, and registered from the web end as:
public static IWindsorContainer RegisterWcfService<TS, TI>(this IWindsorContainer container)
where TI : TS
where TS : class
{
container.Register(Component.For<TS>().ImplementedBy<TI>().Named(typeof(TI).Name)
.Interceptors<LoggingInterceptor>()
.Interceptors<ExceptionHandlerInterceptor>()
.LifeStyle.Transient
.AsWcfService(
GetServiceModel<TS, TI>()
));
return container;
}
As suggested in other threads, we are using
container.Kernel.ReleasePolicy = new NoTrackingReleasePolicy();
to ensure components should be correctly released. We are not explicitly disposing of any of our service references, although I believe the above should be enough. Does anyone have any recommendations or suggestions on where our leak might be coming from?
Unfortunately, manually managing disposal of WCF proxies is the most reliable way to ensure the release of memory for garbage collection and the release of network resources. This brief blog post explains some of the issues that cause WCF proxies to leak memory & network resources. Since you already configure the container to create transient proxy instances, you should wrap your service call logic in a pattern similar to the one shown in the article.
If this doesn't solve your issue, you many need to wade through a memory dump using WinDbg to find what the actual GC root holding a reference chain to the SlidingWindow instances.
PS: Don't be tempted to use a longer lived scope (request or perish the thought, a singleton) to try to solve this issue. The solution is proper disposal of the proxy instances. I found this out the hard way... ;-)
Related
I am constructing a web service that receives data and updates it periodically. When a user pings the service, it will send specific data back to the user. In order to receive this data, I have a persistent that is created on startup and regularly receives updates, but not at periodic intervals. I have already implemented it, but I would like to add DI and make it into a service. Can this type of problem be solved with a BackgroundService or is this not recommended? Is there anything better I should use? I originally wanted to just register my connection object as a singleton, but since singletons are not initialized on startup, that does not work so well for me.
I thought I would add an answer as so expand on my comment. From what you have described, creating a BackgroundService is likely the best solution for what you want to do.
ASP.NET Core provides an IHostedService interface that can be used to implement a background task or service, in your web app. They also provide a BackgroundService class that implements IHostedService and provides a base class for implementing long running background services. These background services are registered within the CreateWebHostBuilder method in Program.cs.
You can consume services from the dependency injection container but you will have to properly manage their scopes when using them. You can decide how to manage your BackgroundService classes in order to fit your needs. It does take an understanding of how to work with Task objects and executing, queueing, monitoring them etc. So I'd recommend giving the docs a thorough read, so you don't end up impacting performance or resource usage.
I also tend to use Autofac as my DI container rather than the built in Microsoft container, since Autofac provides more features for resolving services and managing scopes. So it's worth considering if you find yourself hitting a wall because of the built in container.
Here's the link to the docs section covering this in much more depth. I believe you can also create standalone service workers now, so that might be worth a look depending on use case.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.1&tabs=visual-studio
Edit: Here's another link to a guide an example implementation for a microservice background service. It goes a little more in depth on some of the specifics.
https://learn.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice#implementing-ihostedservice-with-a-custom-hosted-service-class-deriving-from-the-backgroundservice-base-class
I have a non-singleton WCF (standalone) service running some COM objects. In non-WCF environments, using Thread.Start, these COM objects happily run in parallel in different threads, utilising all CPUs and completing around the same time.
However, when I try using them in a specific WCF service, things get strange.
When in the registry ApartmentState is set to Both, WCF works, but the tasks seem to be serial, waiting for each other's completion. The CPU usage never exceeds a share of 1 CPU. It's as it is forced to run in STA.
When in the registry ApartmentState is set to Free, it crashes.
I simply don't get it. Is this some kind of piece of plumbing getting in the way?
My WCF service class has the following attributes:
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any, InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
The COM objects are static / global.
Looks like I might have an answer. Posting in case someone else comes across a similar mystery. The older version was STA only, and the Interop was set to be embedded. Additionally, a prototype of a method was changed. Seemingly, parts taken from the embedded Interop clashed with the COM itself.
Once I changed the setting to No and recompiled everything, it become normal.
I'm using StructureMap and I've configured ISession with HybridHttpOrLocalThreadStorage life cycle. New session is created and injected into controllers on per request basis.
Now, the question I have is about disposal. I've read number of articles presenting number of different approaches. Some people were doing it in controllers, some in repositories, some in http modules and others did it in Application_EndRequest() handler. Critique ranged from SRP violations to 'the one creating an object should be responsible for its disposal' to name a few.
So the bottom line is that:
common approach was to manually dispose these sessions - why? I have already configured my container to manage particular object's life cycle. Shouldn't it (i.e. IoC) manage it for me?
out of options available for disposal is handling it in Application_EndRequest() "the best" way of going about it?
For example, this article explains in length one available approach but the article itself is over 2.5 years old. Perhaps new version of StructureMap makes most of that implementation obsolete?
If you are using RavenDB .net client you will be using DocumentStore and DocumentSession. Both of these object do a fair amount of work in the background; local caching to mention one thing. Just to keep things clean and efficient, each session should call session.dispose() when the work is done. documentStore.Dispose() should be called when the application ends.
I have some code that gets run a lot (for every webservice request).
The code is called from within a web service which is hosted by an application server (Websphere 7).
I noticed Websphere uses a lot of classes that presumably are singleton objects (such as BOXMLSerializer (for de/serializing business objects) or BOFactory.
I want to save on the cost of creating a new object for every web service request for example.
Is creating a singleton that lives for the duration of the uptime of the app server is the best way of dealing with this?
Does Websphere provides any help with these sorts of things?
erloewe is correct, an ordinary singleton could work. Regarding the Singleton Session Bean though -- it's part of the J2EE6 spec and is not available in WAS7 (since it is only J2EE5). It will be part of WAS8 though.
Yes, you could make an ordinary singleton. However due the way the classloader works it might not be exactly same for your applications if you had several applications requiring similar service. For that reason you probably should create a Singleton Session Bean.
I'm developing and application that runs as a Windows service. There are other components which include a few WCF services, a client GUI and so on - but it is the Windows service that access the database.
So, the application is a long-running server, and I'd like to improve its performance and scalability, I was looking to improve data access among other things. I posted in another thread about second-level caching.
This post is about session management for the long-running thread that accesses the database.
Should I be using a thread-static context?
If so, is there any example of how that would be implemented.
Every one around the net who is using NHibernate seem to be heavily focussed on web-application style architectures. There seems to be a great lack of documentation / discussion for non-web app designs.
At the moment, my long running thread does this:
Call 3 or 4 DAO methods
Verify the state of the detached objects returned.
Update the state if needed.
Call a couple of DAO methods to persist the updated instances. (pass in the id of the object and the instance itself - the DAO will retrieve the object from the DB again, and set the updated values and session.SaveOrUpdate() before committing the transaction.
Sleep for 'n' seconds
Repeat all over again!
So, the following is a common pattern we use for each of the DAO methods:
Open session using sessionFactory.OpenSession()
Begin transaction
Do db work. retrieve / update etc
Commit trans
(Rollback in case of exceptions)
Finally always dispose transaction and session.Close()
This happens for every method call to a DAO class.
I suspect this is some sort of an anti-pattern the way we are doing it.
However, I'm not able to find enough direction anywhere as to how we could improve it.
Pls note, while this thread is running in the background, doing its stuff, there are requests coming in from the WCF clients each of which could make 2-3 DAO calls themselves - sometimes querying/updating the same objects the long running thread deals with.
Any ideas / suggestions / pointers to improve our design will be greatly appreciated.
If we can get some good discussion going, we could make this a community wiki, and possbily link to here from http://nhibernate.info
Krishna
There seems to be a great lack of documentation / discussion for non-web app designs.
This has also been my experience. However, the model you are following seems correct to me. You should always open a session, commit changes, then close it again.
This question is a little old now, but another technique would be to use Contextual Sessions rather than creating a new session in each DAO.
In our case, we're thinking of creating the session once per thread (for our multi-threaded win32 service), and make it available to the DAOs using either a property that returns SessionFactory.GetCurrentSession() (using the ThreadContext current session provider, so it's session-per-thread) or via DI (dependency injection - once again using ThreadContext.)
More info on GetCurrentSession and Contextual Sessions here.
You can also flush the session without actually closing it and it achieves the same thing. I do.
We've recently started using an IoC container to manage session lifecycle, as a replacement for the contextual sessions mentioned above. (More details here).
I agree, there aren't many examples for stateful apps.
I'm thinking of doing the following:
Like you I have a windows service hosting a number of WCF services. So the WCF services are the entry points.
Ultimately all my WCF services inherit from AbstractService - which handles a lot of logging and basic DB inserts/updates.
In one of the best NHibernate posts I've seen, a HttpModule does the following:
see http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx
private void BeginTransaction(object sender, EventArgs e) {
NHibernateSessionManager.Instance.BeginTransaction();
}
private void CommitAndCloseSession(object sender, EventArgs e) {
try {
NHibernateSessionManager.Instance.CommitTransaction();
}
finally {
NHibernateSessionManager.Instance.CloseSession();
}
}
So perhaps I should do something similar in AbstractService. So effectively I'll end up with a session per service invocation. If you examine the NHib best practices article link above, you'll see that the NHibernateSessionManager should deal with everything else, as long as I open and close the session (AbstractService constructor and destructor).
Just a thought. But I'm experiencing errors because my session seems to be hanging around for too long, and I'm getting the infamous error - NHibernate.AssertionFailure: null id in entry (don't flush the Session after an exception occurs).