Castle Windsor DI container memory leaks - memory-leaks

I am using Castle Windsor DI container in my WCF app server. In this case the lifetime is per-request: a new service instance is created, container is created and installed, some components are resolved, come work is done and all is disposed.
However, after some amount of requests there is increasing memory consumption of my app server. I was able to find out when I comment out the DI usage the memory problems disappear. But when I install the container and resolve some component, there are some "memory leaks".
I found some articles and posts talking about lifecycles. But all of them are bound to container instance. Since my container lives just during the request there must be everything destroyed when disposing it.
My service implements IDisposable and in the Dispose method I call the container.Dispose as well. However memory usage grows on and on.
Using dotMemory profiler I can see there are survivors and new instances of ProxyGenerationOptions and some other classes.
Am I missing something? Why the container is not releasing all used memory after Dispose is called?

I had a similar problem
I solved it, when I created the proxy class, I served the ModuleScope object
public static class ProxyFactory
{
private static ModuleScope _moduleScope = new ModuleScope(false, false);
public static TClass CreateProxy<TClass>(TClass instance)
{
ProxyGenerator proxy = new ProxyGenerator(new DefaultProxyBuilder(_moduleScope));
List<Type> interfaces = new List<Type>();
interfaces.AddRange(instance.GetType().GetInterfaces());
TClass result = proxy.CreateClassProxyWithTarget(
instance.GetType(),
interfaces.ToArray(),
instance, ......
}
}

Related

Azure Socket Leaks?

I have an ASP.NET Core a website with a lot of simultaneous users which crashes many times during the day and I scaled up and out but no luck.
I have been told my numerous Azure support staff that the issue is that I'm sending out a lot of database calls although database utilization improved after creating indexes. Can you kindly advise what you think the problem is as I have done my best...
I was told that I have "socket leaks".
Please note:
I don't have any external service calls except to sendgrid
I have not used ConfigureAwait(false)
I'm not using "using" statements or explicitly disposing contexts
This is my connection string If it may help...
Server=tcp:sarahah.database.windows.net,1433;Initial Catalog=SarahahDb;Persist Security Info=False;User ID=********;Password=******;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Max Pool Size=400;
These are some code examples:
In Startup.CS:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
Main class:
private readonly ApplicationDbContext _context;
public MessagesController(ApplicationDbContext context, IEmailSender emailSender, UserManager<ApplicationUser> userManager)
{
_context = context;
_emailSender = emailSender;
_userManager = userManager;
}
This an important method code for example:
string UserId = _userManager.GetUserId(User);
var user = await _context.Users.Where(u => u.Id.Equals(UserId)).Include(u => u.Messages).FirstOrDefaultAsync();
// some other code
return View(user.Messages);
Please advise as I have tried my best but this is very embarrassing to me in font of my customers.
Without the error messages that you're seeing, here's a few ideas that you can check.
I'd start with going to your Web App's Overview blade in the Azure Portal. Update the monitoring graph to a time period when you're experiencing problems. Are you CPU bound? Have you exhausted memory? Also, check the HTTP Queue length. If your HTTP queue is really long, it's because your server is choking trying to service the requests and users are experiencing timeout issues.
Next, jump over to your SQL Server's Overview blade in the Azure Portal, and look at the resource utilization chart. Set the time period on the chart to when you're experiencing problems. Have you pegged out your DTUs for your database? If so, it's a sign of poor indexing, poor schema design, or you're just undersized and need to scale up.
Turn on ApplicationInsights if you haven't already. You can use the ApplicationInsights API to insert your own trace statements into your code. Or, you might be able to see exceptions causing the issue without having to do your own tracing.
Check the Kudu logs for your Web Apps.
I agree with Tseng - your usage of EF and .NET Core's DI framework looks correct.
Let us know how the troubleshooting goes and provide additional information on exactly what kind of errors you're seeing. Best of luck!
It looks like a DI issue to me. You are injecting ApplicationDbContext context. Which means the ApplicationDbContext will be resolved from the DI container meaning it will stay open the entire request (transient) as Tseng pointed out. It should be a scoped.
You can inject IServiceScopeFactory scopeFactory in your controller and do something like:
using (var scope = _scopeFactory.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
}
Note that if you are using ASP.NET Core 1.1 and want to be sure that all your services are being resolved correctly change your ConfigureService method in the Startup to:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// Register services
return services.BuildServiceProvider(validateScopes: true);
}

CDI multithreading

We want to optimize our application. There is some streight linear work going on, that can be executed in multiple threads with smaller working sets.
Our typical service is accessed using the #Inject annotation from within our CDI-managed beans. Also such a service could have it's own dependencies injected, i.e.:
public class MyService {
#Inject
private OtherService otherService;
#Inject
private DataService1 dataService1;
...
public void doSomething() {
...
}
}
Because I can not use #Inject inside the class implementing Runnable. (It's not container managed.) I tried to pass the required services to the class before starting the thread. So, using something like this, makes the service instance (myService) available within the thread:
Class Thread1 implements Runnable{
private MyService myService
public Thread1(MyService myService){
this.myService = myService;
}
public void run(){
myService.doSomething();
}
}
Following the call-hierarchy the call to doStometing() is fine, because a reference to myService has been passed. As far as I understand CDI, the injection is done the moment the attribute is accessed for the first time, meaning, when the doStomething() method tries to access either otherService or dataService1, the injection would be performed.
At that point however I receive an exception, that there is no context available.
I also tried to use the JBossThreadExecuter class instead of Plain-Threads - it leads to the very same result.
So the question would be, if there is a nice way to associate a context (or request) with a created Thread?
For EJB-Beans, I read that marking a method with #Asynchronous will cause the method to be run in a managed thread which itself will be wired to the context. That would basically be exactly what I'm searching for.
Is there a way to do this in CDI?
Or is there any way to obtain a context from within a unmanaged thread?
Weld allows programmatic context management, (there's an example in the official docs).
But before you go this way give EJBs a chance )
#Async invocation functionality is there exactly for your case. And as a bonus you'll get timeout interception and transaction management.
When you kick off an async process, your #RequestScoped and #SessionScoped objects are no longer in scope. That's why you get resolution errors for the injected #RequestScoped objects. Using #Stateless without a CDI scope is essentially #Dependent. You can use #ApplicationScoped objects or if you're on CDI 1.1 you can start up #TransactionScoped.
You have to use JavaEE 7 feature, the managed executor. So it will provide a context for your runnable. I'm not sure if your JBoss version is JavaEE 7 compatible. At least Glassfish 4 is, and that approach works.
See details here
Easiest Solution one can think of is Ejb Async.
They are powerful, does the job and most importantly the concurrency is handled by the container(which could be an issue at some point of time if its not properly managed).
Just a simple use case lets say if we have written a rest service and each request spawns 10 threads(ex using CompletableFuture or anything) to do some long processing tasks and for an instance if 500 requests are made then how will the threads be managed, how the app behaves, does it waits for a thread from the thread pool, what is the timeout period, etc etc and to add to our comfort what happens when the threads are Deamon Threads. We can avoid these overheads to some extent using EJBs.
Its always a good thing to have a friend from the technical services team to help us with all these container specific implementations.

ServiceStack ORMLite Bug

Is there anywhere to report bugs/ request features in ServiceStack?
While using ServiceStack, my ServiceStack.ServiceInterface.Service object was throwing this error:
ExecuteReader requires an open and available Connection. The connection's current state is closed.
The Service class includes a Db property (used in examples), which is a IDbConnection - db connections are not thread safe.
I'm interested to know why this non thread safe method of access a database is included in the Service class. It's no good for servicing multiple web service requests.
Service.cs will try to resolve an IDbConnectionFactory that will create a new IDbConnection for you, so there isn't a thread safety issue here.
If you'd like to handle it differently, you can override it.
private IDbConnection db;
public virtual IDbConnection Db
{
get { return db ?? (db = TryResolve<IDbConnectionFactory>().OpenDbConnection()); }
}
Source:
https://github.com/ServiceStack/ServiceStack/blob/ada0f43012610dc9ee9ae863e77dfa36b7abea28/src/ServiceStack/Service.cs#L68
Edit:
Maybe it's not clear that OrmLiteConnectionFactories automatically create a new connection in conjunction with an OpenDbConnection call, but they do:
Source:
https://github.com/ServiceStack/ServiceStack.OrmLite/blob/db40347532a14441eba32e575bcf07f3b2f45cef/src/ServiceStack.OrmLite/OrmLiteConnectionFactory.cs#L72

Multithreaded Singleton in a WCF - What is the appropriate Service Behavior?

I have a class (ZogCheckPublisher) that implements the multithreaded singleton pattern. This class is used within the exposed method (PrintZogChecks) of a WCF service that is hosted by a Windows Service.
public class ProcessKicker : IProcessKicker
{
public void PrintZogChecks(ZogCheckType checkType)
{
ZogCheckPublisher.Instance.ProcessCheckOrCoupon(checkType);
}
}
ZogCheckPublisher keeps track of which 'checkType' is currently in the process of being printed, and rejects requests that duplicate a currently active print request. I am trying to understand ServiceBehaviors and the appropriate behavior to use. I think that this is appropriate:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
One instance of the service that is multithreaded. If I am understanding things rightly?
Your understanding is correct.
The service behavior will implement a single multithreaded instance of the service.
[ServiceBehaviorAttribute(Name = "Test", InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple]
In a singleton service the configured concurrency mode alone governs the concurrent execution of pending calls. Therefore, if the service instance is configured with ConcurrencyMode.Multiple, concurrent processing of calls from the same client is allowed. Calls will be executed by the service instance as fast as they come off the channel (up to the throttle limit). Of course, as is always the case with a stateful unsynchronized service instance, you must synchronize access to the service instance or risk state corruption.
The following links provide additional Concurrency Management guidance:
Multithreaded Singleton WCF Service
http://msdn.microsoft.com/en-us/library/orm-9780596521301-02-08.aspx
Regards,

Hibernate Session Threading

I have a problem regarding Hibernate and lazy loading.
Background:
I have a Spring MVC web app, I use Hibernate for my persistence layer. I'm using OpenSessionInViewFilter to enable me to lazy load entities in my view layer. And I'm extending the HibernateDaoSupport classes and using HibernateTemplate to save/load objects. Everything has been working quite well. Up until now.
The Problem:
I have a task which can be started via a web request. When the request is routed to a controller, the controller will create a new Runnable for this task and start the thread to run the task. So the original thread will return and the Hibernate session which was put in ThreadLocal (by OpenSessionInViewFilter) is not available to the new thread for the Task. So when the task does some database stuff I get the infamous LazyInitializationException.
Can any one suggest the best way I can make a Hibernate session available to the Task?
Thanks for reading.
Make your Runnable a Spring bean and add #Transactional annotation over run. You must be warned thou that this asynchronous task won't run in the same transaction as your web request.
And please don't start new thread, use pooling/executor.
Here is a working example on how to use the Hibernate session inside a Runnable:
#Service
#Transactional
public class ScheduleService {
#Autowired
private SessionFactory sessionFactory;
#Autowired
private ThreadPoolTaskScheduler scheduler;
public void doSomething() {
ScheduledFuture sf = scheduler.schedule(new Runnable() {
#Override
public void run() {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(scheduler);
final Session session = sessionFactory.openSession();
// Now you can use the session
}
}, new CronTrigger("25 8 * * * *"));
}
}
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext() takes a reference to any Spring managed bean, so the scheduler itself is fine. Any other Spring managed bean would work as well.
Do I understand correctly, you want to perform some action in a completely dedicated background thread, right? In that case, I recommend you not accessing the Hibernates OpenSessionInViewFilter and further session logic for that thread at all, because it will, is you correctly noted, run in a decoupled thread and therefore information loaded in the original thread (i.e, the one that dealt with the initial HttpRequest). I think it would be wise to open and close the session yourself within that thread.
Otherwise, you might question why you are running that operation in a separated thread. May be it is sufficient to run the operation normally and present the user with some 'loading' screen in the meantime?

Resources