Hi,
I am creating a very complex XamDataGrid using code. Once loaded, the grid consumes around 400mb of RAM.
Some actions in my application require removing the old XamDataGrid and adding a new one.
The problem is when i remove the old XamDataGrid , its memory is still not freed. Then addition of new grid consumes another 400mb ram. Multiple iterations of this action ultimately results in SystemOutOfMemory exception.
Here is how i am removing XamDataGrid.
SelectedGrid is the parent.
SelectedGrid.Children.Remove((XamDataGrid)SelectedGrid.Children.Cast<UIElement>().First(e1 => Grid.GetRow(e1) == 4 && Grid.GetColumn(e1) == 1));SelectedGrid.UpdateLayout();
I even tried forcefully calling the GC. But it still does not frees up the memory.
Hello,
There is no out of the box way to clear the instances of XamDataGrid from the memory. All you need to do is to ensure that you're not holding a reference to the control since that would be blocking the GC from collecting it.
I would suggest to try and running a memory profiler against your application so you could identify what kind of objects are not cleared from memory. Using a memory profiler could help you out to find out if you have a reference to the XamDataGrid control.
By the way I'm curios what is the lifetime of the data that is fed to the XamDataGrid compared to the lifetime of a particular instance of the grid? If the data lives longer than the grid itself there is slight chance that this could be a "memory leak" in the grid.
If you provide a sample project illustrating the issue I would be able to do this mem profiling myself and be able to give you more concrete directions.
Hope this was helpful.
Thanks for the reply Konstantin.
I tried the profiler, sadly it created huge profiler report which takes ages to open.
I was able to speed up things and improve memory consumption by setting ItemContainerGenerationMode to LazyLoad.
However, i need to perform certain operations on grid after it is loaded. Earlier i was doing so in grid_Loaded event. Now i do the same in grid_RecordsInViewChanged to perform those actions on records in the view. The problem here is if i scroll back to already loaded records, grid_RecordsInViewChanged is called again and all the operations are re-done on those records which is no more needed as those actions were already applied to them. Is there any way to check if the records in view are newly loaded or are already loaded ones?
With regard to the huge profile file you have not tried it already you could try and reduce the data that you’re feeding to the XamDataGrid so it won’t need so much memory that the profiler will try to track and get a reasonably sized profile result file.
Did you verify that the allocated memory is being freed in this scenario? My suspicion is that this just would decrease the allocated memory(allocating memory only for the items that entered view) so you’ll probably need more iterations of adding/removing the grid to reach to the point where StackOverflowException is thrown.
What kind of operations are you performing on the Records? Are you doing something on the UI or they are more oriented towards the data of the record?
Another way to go here might be to know/check somehow weather you've processed this record and if so just skip it.
You could also try using the InitializedRecord event if these operations that you’re performing are more data related.
It could be helpful if you could provide some more details on the scenario you're trying to achieve so I could be of more help.
For Profiler, I will try reducing the data and will get back to you with any outcome.
For LazyLoading,
Though i also suspected that allocated memory will eventually increase with multiple iterations, but looking in RAM consumption as a whole after performing all the operations i was performing with preload, its much lesser. I even saw occational drop in RAM usage and many times constant usage without any spike. I will contune observing the pattern.
For post gird loading operations,
There are certain columns which are added dynamically to the grid(which are not a part of its datasouce). I need to compute their values based on other cell values of each row. Also, some cells have values dependant on other cells and their CellValuePresenter is decided on runtime based on other values. The design of the screen is such that no control or binding or converter is written in the xaml file. Everything is in the a separate .cs file. Each object is dynamically created.
I will try to get a sample project ready in some time.
Meanwhile, i am trying to achive these above mentioned scenarios. Is there any way to know if the given DataRecord is already loaded or it is being loaded for the first time?
Sorry for the late reply.
Did you tried using the InitializeRecord event I mentioned in my previous response. looking at the operations that you;re looking at it seems that this is perhaps what you need.
You could look at the following help article where exactly such unbound values are calculated using the InitializeRecord. You could also find the following sample useful - it's demonstrating similar scenario using the same event to do some unbound value calculations.
Let me know if this event works for your scenario and don't hesitate to ask if you need more assistance with this.