Context: I have a set of View/Presenters and I've noticed that for complex views I get some performance issues at the time of the InitializeComponent() call
Is there any way to instruct the spring container to pre-instantiate objects scoped as prototype? Something similar to a queue with the objects ready when the application requests them?
We had exactly the same problem. We also found that this performance overhead occured only the first time we requested a form from the container. We didn't find a clean solution, so we decided to write an initialization routine that runs in the background and requests all objects of type Form from the container. When this routine is finished, all forms open quickly.
Looking forward to a better sution, but this worked for us. Main disadvantage of this workaround is, that during the initialization routine, users might still experience some slow loading forms.
Related
I am working to resolve why my Blazor App seems to eat memory until the application pool is forced to recycle due to 4 gigs of memory being used.
First, this is a default template memory usage snapshots. It's about what would be expected. I clicked around a bunch, opened and closed the page multiple times, and the memory usage is stable.
This is the Customer Service App. I start the app on the empty home page, then go to Page1. Then I take snap shot, and go back to the home page, then back to Page1. Each time I so this, the memory gets higher and higher.
This is what the object list looks like. It's not clear to me what the issue is. Is there cleanup I should be doing when the user navigates away from a page to ensure that the memory is cleaned up?
When this app is published to the network IIS machine, it eats up memory until the limit of 4 gigs is reached. This occurs with only 1 or two people using the app at a time. So there must be some sort of memory issue to be resolved. The app itself is running fine, it's just the memory issue I am trying to resolve.
Since this question now has over a thousand view, I am going to post a response here on this.
First, make sure you have IDisposable on your pages.
Second, there was no single issue that I found that resolved the issue. The issue was resolved, and it now works as expected, but it took serious digging to find the issues. I just used the Visual Studio memory tools and looked for objects that were not getting released as expected. A blazor server app runs heavily on the server, and if there are references that are not getting released, it holds the object in memory and you have a memory leak.
While I always assumed memory leaks were a thing of the past with .net, it clearly was not the case.
So make sure you are careful with all object references and make them all as narrow (localized) as possible, especially anything dealing with Entity Framework like context. Read the docs on how a context should be used and disposed as frequently as possible.
Hope this helps, that's all I got.
I have created many Blazor applications and investigated this issue fairly thoroughly.
This issue was posted and has lots of good info: https://github.com/dotnet/aspnetcore/issues/43221
Here is also a link on the difference GC modes: https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/workstation-server-gc
I first tried manually calling the GC in a Hosted Service every 5 seconds. This worked, but just seemed to be a hack.
GC.Collect(2, GCCollectionMode.Forced);
However, after reading the above, I decided that turning off Server Garbage Collection was the better solution. To do this, I just edited by project file to include the following property group item.
<PropertyGroup>
<ServerGarbageCollection>false</ServerGarbageCollection>
</PropertyGroup>
This basically makes the GC more aggressive.
#inherits ComponentBase
// Implement the OnNavigatedFrom method
protected override void OnNavigatedFrom(NavigationContext navigationContext)
{
// Perform any cleanup tasks here
// ...
// Call the base method to ensure proper handling of the event
base.OnNavigatedFrom(navigationContext);
}
In the example above, we implement the OnNavigatedFrom method in our component. Inside the method, we perform any necessary cleanup tasks, such as disposing of unused objects or releasing resources. We then call the base implementation of the OnNavigatedFrom method to ensure that the event is handled properly by the Blazor framework. This will ensure that the memory is properly cleaned up when a user navigates away from the page.
I'm currently investigating some code which has a cache layer which at the bottom level uses the MemoryCache class. This is a c# Windows Service app so not web/IIS. There is a section of the code which spawns off a number of threads in which it creates and executes some code in a POC to perform some calculations. These are then stored in the above mentioned cache layer. What is been seen is it looks like cached values seem to be getting stored per thread and not at apication level. I thought that MemoryCache was a Singleton that would sit out side of the individual threads.
Can anybody confirm this behaviour would be expected?
Many thanks for any comments.
A MemoryCache is thread-safe but there is no reason to assume it's a singleton. If you want different threads to access the same MemoryCache instance you need to give them all a reference to the same instance (either as a singleton (really bad) static (still bad) or through argument passing as dependency injection (good)).
The simple way to do it (which does use global state) is to access the default memory cache:
var cache = MemoryCache.Default; // not really a good idea and harder to test, works
You can find the specific docs here. Make sure to configure it in your app/web.config file.
We are using the petapoco repository pattern (similar to this blog post). As the page loads we open up the repository, run the query, dispose and then carry on processing. This is fine on light pages, but when this happens a few times in the page we get quite significant performance degradation.
I had, perhaps wrongly, assumed that connection pooling would cope with this, which is enabled.
I ran a couple of tests.
The page it's on (it's an aspx page) takes around 1.2 seconds to load as it is at the moment. The page is running around 30 database queries...and, looking at the profiler, is doing a login and logout per query (even with connection pooling).
If I persist the connection and don't close until the page ends, this drops to around 70ms, which is quite a significant saving.
Perhaps we need to keep the Database object hanging around for the request, but I didn't think PetaPoco had this much of an overhead...particularly with the connection pooling.
I have created a test app to demonstrate it.
This demonstrates that loading a user 1000 times takes 230ms if the repository is reused, but takes 3.5seconds if the repository is recreated every time.
Your usage of connection pooling is breaking best practices.
It says nowhere to get rid of it after every statement. I normally keep a connection / repository around while doing processing and only close it when my function is finished (with MVC).
Yes, even the connection pool has overhead and you seem to be really bound on making that show.
What I always do is create a single instance of my repository per request. Because I develop almost exclusively using the MVC pattern, that means I create a private class level variable in each of my controllers and use it to service any requests within my Action methods. Translated to WebForms (ASPX), that means I would create one in the BeforeLoad (or whatever the event just before PageLoad is) and pass it around as needed. I don't think keeping a class-level instance is a good idea for Webforms though, but I can't remember enough to be sure.
The rule of thumb is to use one instance of your repo (or any other type of class really) for the entirety of your request, which is usually a page load or Ajax call. And for the reasons you've pointed out.
Remember: information on the internet is free, and you get what you pay for.
A Programmer in my office has written an incredibly large application in Windows Forms. Anyways, he keeps having trouble with the application slowing down after about 12 hours. We have confirmed that it is the actual Event Loop that ends up running slowly and not the code after the events fire. For instance, even typing into a textbox will be extremely slow. He has several socket communication threads, which we have confirmed are running at normal speed. The only thing I can think of is that he has several System.Timers.Timer instances throughout the application. Could they be the problem? The program slows down usually after no one has been using it for about 5 or 6 hours.
I know there could be a long list of possible issues. We just need some advice on where to start looking. I have tried all of the obvious.
One other thing to mention. His architecture consists of a base form, which includes a panel with controls that every page has along with 3 timers, and all other forms inherit from this base form. There are probably 15 or so of these forms, all of which are loaded into memory at startup. We did this, because the client was complaining about switching between the forms the first time took a few seconds. Each form has potentially fifty to one hundred instances of a control we wrote for him to use which does all of his back-end work. There is a static timer in this control and one static thread as well--since there is only one instance regardless of how many instances of the control are in memory, I can't imagine that those are the issue. Also the base form's timers are static.
I cannot vouch for the efficiency of his code, but it does run really well at our office, and for 5 to 6 hours on site.
Any ideas?
Edit:
I just talked to the guy on site and he asked. 1st, the event handler for one of the static timers is not static--how that it is possible for a static timer to access an instance method seems weird to me. Second, the timers' AutoReset is set to true.
Update:
Ok, I finally got with the guy today to look at some of the code.
He had several static members of his class, i.e. the timers, some buttons, and user controls. Then in the constructor he was using the new operator on each of those static members without a static bool isInit flag.
In other words, the static members were being initialized each time a new form was created but only the last one initialized was being referenced. However, I would imagine that the Form Container was holding references to the old objects so the old objects would never get deleted. Also, wouldn't this be bad aliasing for the containers if the object were to be deleted when the static member's reference was changed? Either way, a bad leak, or a bad alias would cause problems. I am hoping that is the only problem. I am having him fix all of that and then we will test again.
To add insult to injury, he was calling GC.KeepAlive(the static timer) that had a new reference inside the constructor. So, he had 21 timers running.
Are you disposing? Are you holding objects in memory? Are you holding on to some other unmanaged resource.
Leave it running, wait till it gets slow, attach a debugger, step through and see which lines are slow in your problem area.
EDIT:
If it only goes slow on site then, if the product is for a specific client you should construct a reference environment that matches the clients as closely as possible. This would be both useful for the future, and useful now for identifying the differences between your systems which are likely the cause of the problem.
I did have a similar sounding issue where we performed some remoting over sockets on background threads between several services on different machines. Unfortunately I can't remember the exact details (sigh.) As I recall we kept requesting at a set time interval but, the reponse time from the service got slower over time, eventually the response time exceded the set interval. This was fine for the first 1000 or so calls, .Net kept a nice growing stack of the callbacks we were expecting. However, eventually this list reached some internal limit and the message pump froze, including all the painting on client GUIs. This was resolved by ensuring that we would not call until we had had a response. This kind of race condition may or may not be what you are experiencing but I thought it may be worth mentioning.
At the new place I am working, I've been tasking with developing a web-application framework. I am new (6 months ish) to the ASP.NET framework and things seem pretty straight forward, but I have a few questions that I'd like to ask you ASP professionals. I'll note that I am no stranger to C#.
Long life objects/Caching
What is the preferred method to deal with objects that you don't want to re-initialize every time a page is it? I noticed that there was a cache manager that can be used, but are there any caveats to using this? For example, I might want to cache various things and I was thinking about writing a wrapper around the cache that prefixed cache names so that I could implement different caches using the same underlying .NET cache manager.
1) Are there any design considerations I need to think about the objects that I am want to cache?
2) If I want to implement a manager of some time that is around during the lifetime of the web application (thread-safe, obviously), is it enough to initialize it during app_start and kill it in app_end? Or is this practiced frowned upon and any managers are created uniquely in the constructor/init method of the page being served.
3) If I have a long-term object initialized at app start, is this likely to get affected when the app pool is recycled? If it is destroy at app end is it a case of it simply getting destroyed and then recreated again? I am fine with this restriction, I just want to get a little clearer :)
Long Life Threads
I've done a bit of research on this and this question is probably redundant. It seems it is not safe to start a worker thread in the ASP.NET environment and instead, use a windows service to do long-running tasks. The latter isn't exactly a problem, the target environments will have the facility to install services, but I just wanted to double check that this was absolutely necessary. I understand threads can throw exceptions and die, but I do not understand the reasoning behind prohibiting them. If .NET provided a a thread framework that encompassed System.Thread, but also provided notifications for when the Application Server was going to recycle the App-Pool, we could actually do something about it rather than just keel over and die at the point we were stopped.
Are there any solutions to threading in ASP.NET or is it basically "service"?
I am sure I'll have more queries, but this is it for now.
EDIT: Thankyou for all the responses!
So here's the main thing that you're going to want to keep in mind. The IIS may get reset or may reset itself (based on criteria) while you're working. You can never know when that will happen unless it stops rendering your page while you're waiting on the response (in which case you'll get a browser notice that the page stopped responding, eventually.
Threads
This is why you shouldn't use threads in ASP.NET apps. However, that's not to say you can't. Once again, you'll need to configure the IIS engine properly (I've had it hang when spawning a lot of threads, but that may have been machine dependent). If you can trust that nobody will cause ASP.NET to recompile your code/restart your application (by saving the web.config, for instance) then you will have less issues than you might otherwise.
Instead of running a Windows service, you could use an ASMX or WCF service which also run on IIS/.NET. That's up to you. But with multiple service pools it allows you to keep everything "in the same environment" as far as installations and builds are concerned. They obviously don't share the same processpool/memoryspace.
"You're Wrong!"
I'm sure someone will read this far and go "but you can't thread in ASP.NET!!!" so here's the link that shows you how to do it from that venerable MSDN http://msdn.microsoft.com/en-us/magazine/cc164128.aspx
Now onto Long life objects/Caching
Caching
So it depends on what you mean by caching. Is this per user, per system, per application, per database, or per page? Each is possible, but takes some contrivance and complexity, depending on needs.
The simplest way to do it per page is with static variables. This is also highly dangerous if you're using it for user-code-stuff because there's no indication to the end user that the variable is going to change, if more than one users uses the page. Instead, if you need something to live with the user while they work with the page in particular, you could either stuff it into session (serverside caching, stays with the user, they can use it across multiple pages) or you could stick it into ViewState.
The cachemanager you reference above would be good for application style caching, where everyone using the webapp can use the same datastore. That might be good for intensive queries where you want to get the values back as quickly as possible so long as they're not stale. That's up to you to decide. Also, things like application settings could be stored there, if you use a database layer for storage.
Long term cache objects
You could initialize it in the app_start with no problem, and the same goes for destroying it at the end if you felt the need, but yes, you do need to watch out for what I described at first about the system throwing all your code out and restarting.
Keel over and die
But you don't get notified when you're (the app pool here) going to be restarted (as far as I know) so you can pretty much keel over and die on anything. Always assume the app is going to go down on you before your request, and that every request is the first one.
Really tho, that just leads back into web-design in the first place. You don't know that this is the first visitor or the fifty millionth (unless you're storing that information in memory of course) so just like the app is stateless, you also need to plan your architecture to be stateless as much as possible. That's where web-apps are great.
If you need state on a regular basis, consider sticking with desktop apps. If you can live with stateless-ness, welcome to ASP.NET and web development.
1) The main thing about caching is understanding the lifetime of the cache, and the effects of caching (particularly large) objects in cache. Consider caching a 1MB object in memory that is generated each time your default.aspx page is hit; and after a year of production you're getting 10,000 hits an hour, and object lifetime is 2 hours. You can easily chew up TONS of memory, which can affect performance, and also may cause things to be prematurely expired from the cache, which in turn can cause other issues. As long as you understand the effects of all of this, you're fine.
2) Starting it up in Application_Start and shutting it down in Application_End is fine. You can also implement a custom HttpApplication with an http module.
3) Yes, when your app pool is recycled it calls Application_End and everything is shutdown and destroyed.
4) (Threads) The issue with threads comes up in relation to scaling. If you hit that default.aspx page, and it fires up a thread, and that page gets hit 10,000 in 2 minutes, you could potentially have a ton of threads running in your application pool. Again, as long as you understand the ramifications of firing up a thread, you can do it. ThreadPool is another story, the asp.net runtime uses the ThreadPool to process requests, so if you tie up all the threadpool threads, your application can potentially hang because there isn't a thread available to process the request.
1) Are there any design considerations I need to think about the objects that I am want to cache?
2) If I want to implement a manager of some time that is around during the lifetime of the web application (thread-safe, obviously), is it enough to initialize it during app_start and kill it in app_end? Or is this practiced frowned upon and any managers are created uniquely in the constructor/init method of the page being served.
There's a difference between data caching and output caching. I think you're looking for data caching which means caching some object for use in the application. This can be done via HttpContext.Current.Cache. You can also cache page output and differentiate that on conditions so the page logic doesn't have to run at all. This functionality is also built into ASP.NET. Something to keep in mind when doing data caching is that you need to be careful about the scope of the things you cache. For example, when using Entity Framework, you might be tempted to cache some object that's been retrieved from the DB. However, if your DB Context is scoped per request (a new one for every user visiting your site, probably the correct way) then your cached object will rely on this DB Context for lazy loading but the DB Context will be disposed of after the first request ends.
3) If I have a long-term object initialized at app start, is this likely to get affected when the app pool is recycled? If it is destroy at app end is it a case of it simply getting destroyed and then recreated again? I am fine with this restriction, I just want to get a little clearer :)
Perhaps the biggest issue with threading in ASP.NET is that it runs in the same process as all your requests. Even if this weren't an issue in and of itself, IIS can be configured (and if you don't own the servers almost certainly will be configured) to shut down the app if it's inactive (which you mentioned) which can cause issues for these threads. I have seen solutions to that including making sure IIS never recycles the app pool to spawning a thread that hits the site to keep it alive even on hosted servers