Dajbych.net


Battle with OutOfMemoryException during UI development

, 3 minutes to read

windows 8 logo

When developing WPF applications for Windows Phone or Windows Store, I quite easily encounter OutOfMemoryException. If I'm trying to view a lot of data and Visual Studio is able to catch this exception, the cause is definitely the high memory consumption of the UI controls. This is especially evident on devices with low memory and with an ARM processor. In this article, I'll show you how to deal with it.

Everything will be texture someday

Each control on the Windows Phone platform can't be wider or taller than 2048 pixels. Do you know why? Because the control is ultimately a texture, and it doesn't matter if it’s Image or TextBlock. A texture takes up quite a lot of memory because it’s a bitmap. This is an order of magnitude larger than the size of an image stored as a file on disk. This is because the image is compressed as a file. These methods can be as simple as PNG, complex as JPEG, and very complex as JPEG XR. The image is compressed mainly to make its transfer from the server to the client as fast as possible. However, at the level of rendering on the display, everything is a bitmap, because you can only work with this representation.

The textures of all window controls are in memory

By window in this article, I mean the parent element declared by the XAML language. Usually it is PhoneApplicationPage or LayoutAwarePage. XAML translates into C# anyway, and eventually creates something that is virtually identical to what Visual Studio generates in code behind when you design a Windows Forms application. After all, even in the case of a XAML application, these codes are located in the obj/Debug directory and you can view them at any time.

The important thing is that everything that the window can display is kept in memory. By word, I mean anything that is not visible, but the user can move to it. These are all control items such as ListBox, Pivot, or GridView. Whenever I set the binding to properties ItemsSource, I think about whether the number of elements will be on the order of tens. If there can be more than one, it is unthinkable to create controls for all items. And that’s what DataTemplate is excellent for and why it’s so easy to get into memory stress.

The solution can be relatively simple, but it always depends on the individual case. Sometimes it is enough to set the property Visibility to the value of Collapsed. Therefore, the correct title of this section should read: In the memory, there are textures of all window controls that have the Visibiliy property set to 'Visible.

Away with the controls

In some cases, however, circumstances require the implementation of a custom control. There is no need to worry about anything, it is usually much faster and ultimately better than trying to bend some other control element to make it look the way it is needed. In the vast majority of cases, it is sufficient to start from class UserControl. I only needed direct rendering via class Graphics (which is the GDI+ wrapper) when I wanted to make a smooth animation in Windows Forms. Therefore, you only need to make a custom control so that it contains as few custom controls as possible. In short, so that the user does not move around the controls, but the data contexts of the controls.

The image above shows elements in memory using a common technique. For each DataContext, a control element is created according to DataTemplate.

This figure represents the memory savings compared to the previous case. A control is no longer created for each ViewModel, but there are only static controls that change their DataContext.