I'm working on an MVVM (WPF) application that features one main container. The view that is displayed depends on a menu item that is selected (e.g. Home, Product Information etc.). Whenever a view is accessed for the first time, memory consumption goes up slightly as the associated view model is instantiated; when the same view is further accessed, memory stays the same since the existing instance of the associated view model is used.
However, one view containing a WebBrowser control increases memory usage by ~80MB each time it is accessed without exception; this memory never gets freed — repeatedly switching between Home and that view can cause the application to run out of memory and crash. Using a memory profiler I discovered that this increase happens in unmanaged code, particularly user32.dll.
Going through other StackOverflow posts, I noticed that there is a recurring problem with WebBrowser and memory leaking, but most posts point towards this being an issue with IE7. We're enforcing the usage of IE11 for our application. I need some help investigating this problem and a potential resolution. I'm afraid I can't post code, but any hint can be helpful.
I found the issue and it has nothing to do with the WebBrowser control being leaky. The code (I didn't write it) passed the instance of WebBrowser from the view to the view model thus making the view model contain a hard reference to the view. Since the lifespan of the view model corresponds to the lifespan of the application, those references to the views were forever held. Replacing that logic with a proper one fixed the issue.
Related
I'm new to mobile development, and by extension, Xamarin. One thing I've always noticed is that any time a page is loaded, people always request to make a new page() as opposed to have a pool or set list of pages they can access.
Won't this cause memory problems? Does Xamarin automatically remove older pages from the scope? Sorry if it sounds like a dumb question, but it's something that threw me off as my first instinct as a programmer is usually to limit unnecessary repeats of data in the memory.
Xamarin is .NET based technology and as such memory management is based on the garbage collection. As such if you follow good practices your generated page that is not needed anymore should be garbage collected at some point.
This is a good question. If you are having a memory leak on the page navigation, you can look at this document first.
The NavigationPage class provides a hierarchical navigation experience where the user is able to navigate through pages, forwards and backwards, as desired. The class implements navigation as a last-in, first-out (LIFO) stack of Page objects.
So you can see that all the pages are on the stack when you are navigating the page. Simply put, xamarin handles their memory release internally as the stack is pushed.
If you are still concerned about memory leaks, you can refer to Xamarin.Forms App Lifecycle to manually release objects based on the end of the page's life cycle.
About Explicit call to garbage collector on navigation back in the stack
This one is a controversial one. Some people say that you should never explicitely call to garbage collector. And, in general, I would agree with this. However, in Xamarin the magic call to GC.Collect() can do wanders. If nothing else helps, just call to GC.Collect(); immidiately after calling await _navigation.PopAsync(true) .
I currently use DevExpress controls heavily in an application. The controls are great and speed-up development time dramatically (and hence, I wouldn't want to ditch them) however, I have a few issues with their performance.
My application is a Shell/Modules/Views&ViewModels application (it follows a lot of the design patterns you would find in Prism).
When a view is first loaded it takes an extremely long time to display (on some of my users PCs with slow machines we're talking 5+ seconds of just hanging there). The time it takes apparently depends on the usage of DX controls (how many ones are on there that haven't been seen before by the application).
When you destroy the view and re-open it, it opens in less than a second. The ViewModel in my test cases/performance profiles has been made to re-create each time - so there is no shared state within my code between invocations of the view (no singleton injected objects).
After a bit of discussion and research I appear to have narrowed down the problem to on-demand loading of the template files for the DX controls.
There is a thread here about that:
http://www.devexpress.com/Support/Center/Issues/ViewIssue.aspx?issueid=Q382256
which references:
http://www.devexpress.com/Support/Center/p/B201967.aspx & DevExpress controls for WPF load time
The solution described in these threads is to either display a loading indicator or to use a hidden window with controls on it at start-up. Neither of these options are something I'd like to do (and the hidden window option didn't appear to gain much performance when I tried a simple example, interestingly - which also suggests that I might be missing something).
What I am hoping to do is to pre-load template files that I know I'm going to need on a background thread. Is there any way I can do this in WPF? (I'm thinking this is more a general WPF thing rather than a DevExpress thing - even if it's something that needs to be implemented in the DX libraries themselves).
Any ideas for either me or the guys at DevExpress?
What you can do in the background thread is to preload all the required assemblies. Also make sure they are nged-ed. The UI controls need to be initialized from the UI thread.
Are silverlight pages initialized every time they are called? InitializeComponent();
Once they are called is this stored in memory?
If they are Initiallzed everytime they are called is there a way to check to see if it has already been rendered so as to bypass the rendering of the page?
A page is an object like any other - if you create one, then navigate to a different page, the original is no longer referenced and becomes eligible for garbage collection. If you visit the page again, you get an all-new instance.
You asked this question in terms of a preconceived solution (avoid page rendering). What is the underlying issue that led you to consider this approach?
Here is the scenerio:
On application open the user is asked to open a "Project"
Inside a project there are processes, categories, tasks, documents and notes.
There are a few more, but lets keep it simple. Most of the items above are lists that are bound to grids or treeviews.
Each of them have a separate database table and are linked with values in the database.
So after a user opens a project I could do something like this:
Get Processes that belong to Project 'A'
Get Categories that belong to each process
Get Tasks that belong to each category
Get Documents that belong to Project 'A'
Get Notes that belong to Project 'A'
and so on
The issue is then if the user closes this Project I have to clear every bound control and clear any variables related, then be ready to open another Project.
So what I am looking for is some advice for the way to handle this type of situation efficiently.
I am using C# .Net, and the application is a Windows Forms application.
Well, any way you slice it, the memory allocations done on load will have to be cleaned up at some point.
Depending on how you do your data access, you may have to do it manually, or .NET's garbage collector may take care of it for you (most likely).
For this type of application (given the limited requirements you've written), I would normally implement it as an MDI application so you could have multiple projects open at once. All of the project loading/disposing code would be run through the child window, so any time a child window is closed, the memory gets cleaned up automatically.
Even if you don't/can't do MDI, I would strongly recommend that you follow the dispose-on-unload model instead of keeping the same form open and reinitializing it with new data. The latter model is very prone to erroneous behaviour because of lingering data and/or state (which is programmer error, but is really difficult or even impossible to track down when trying to reproduce a client's issue). I've seen this pattern a lot in WinForms and it isn't pretty when the form controls and business logic start to get complicated. Dump the form and start again.
We have several different projects using ASP.NET and DevExpress ASPxGridView components. Throughout the development of these projects, several techniques on databinding have been used and we're now finding that some of these projects are eating up all the memory on the server.
Originally, we were using a call to a stored procedure and binding a DataSet to the the gridview, but on DX recommendation, modified this to an ObjectDataSource and created and object that ultimately uses a Linq statement against the DB and returns a generic list of objects which is then bound.
Unfortunately, this does not cure the problem at hand. We're still noticing large amounts of memory being eaten up and I'm trying to get to the bottom of this. When running through RedGate memory profiler, I notice that there are lots of strings, RuntimeTypeHandles and instances of my object created everytime we rebind to the grid.
The DataBind is done on page load, and the grid uses postbacks on sorting, but this is causing MBs of memory to leak on every bind, so I'm wondering what techniques I can use / best practices for managing the objects we have control over? I've implemented IDisposable in the data object, disposing of the linq context and setting any other objects to null, but it doesn't seem to make a difference. I seem to be creating an instance of the data object on every call, and even calling dispose makes no difference.
Wow, lots of plumbing and moving parts in there.
Is it possible to narrow things down a bit? That is, can you strip stuff off the page and see how it performs?
Forgive this, but when you say 'leaking memory' what do you mean and how do you know? The GC is 'lazy' and won't do anything until there is pressure to do so. This is a good thing but it also means memory may appear to accumulate until a collection is needed, and then you may find it frees a lot up. Memory profilers often look like a saw-tooth for this reason.
How are you storing the grid data to make the paging work? I've seen datasets persisted in viewstate, which means the data goes to the client along with the grid. If you're querying again on post-back page-load you're wasting a lot of space there.
Another common problem is event subscriptions keeping large objects alive longer than they should. I've actually seen code where a datagrid was placed in session state which kept the page alive for as long as the session was. On each post-back this happened again and again until poof. In this case, GC couldn't help us becuase the objects were indeed still 'in-use'.
So try to simplify - turn off sorting, get rid of the 3rd party control, use a smaller data set, etc. Using a memory profiler and something that puts the server under pressure, measure this scenario. If you find no 'leaks' then start adding stuff back to see when it goes haywire.
You may be returning too much data to your iis server each time. Remember that using standard linq datasource with the devexpress grid, each time you do a callback for sorting, or paging or any other callback, the whole data is loaded in memory and then sorted and paged.
This means that if you are loading a very large amount of data you will easily waste server memory. Think that you may have much users opening the same page and this will load the whole data in memory for each user, and the GC may not have time enough to free all that stuff.
DevExpress provides for this the LinqServerModeDataSource, that does all the paging and sorting in the data server.
If you cannot use that, try to retrieve a smaller set of data by filtering it.