Bug 45722 - Memory leak in Xamarin Forms ListView
Summary: Memory leak in Xamarin Forms ListView
Status: RESOLVED FIXED
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms (show other bugs)
Version: 2.3.5
Hardware: PC Windows
: Highest normal
Target Milestone: ---
Assignee: E.Z. Hart [MSFT]
URL:
Depends on:
Blocks:
 
Reported: 2016-10-20 08:08 UTC by Blazey
Modified: 2017-12-05 18:58 UTC (History)
26 users (show)

See Also:
Tags: ac, uwp, listview, memoryleak, xamexttriage, android fr
Is this bug a regression?: ---
Last known good build:


Attachments
Sample project and Screenshot (142.95 KB, application/x-rar)
2016-11-10 17:37 UTC, Mike
Details
ViewModel dirty bind memory leak sample project (87.74 KB, application/x-rar)
2016-11-11 06:41 UTC, Mike
Details
TemplateView temporary solution (87.33 KB, application/x-rar)
2016-12-13 17:27 UTC, Mike
Details
MemoryLeakTest - Sample Project for Comment 22 (389.52 KB, application/x-zip-compressed)
2017-07-06 20:16 UTC, MS
Details

Description Blazey 2016-10-20 08:08:47 UTC
I have a memory leak issue in my application. This app is developed with Xamarin Forms. I experience the problem on UWP. 

Here is XAML for the ListView:

<ListView x:Name="listView" HasUnevenRows="True" IsGroupingEnabled="{ Binding IsGroupingEnabled }" GroupDisplayBinding="{ Binding Key }"        ItemsSource="{Binding Model}" SeparatorVisibility="None" SeparatorColor="Gray" BackgroundColor="Transparent"  HorizontalOptions="FillAndExpand">
      <x:Arguments>
        <ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
        <!--<ListViewCachingStrategy>RetainElement</ListViewCachingStrategy>-->
      </x:Arguments>
      <ListView.GroupHeaderTemplate>
        <DataTemplate>
          <ViewCell Height="40">
            <StackLayout VerticalOptions="FillAndExpand"
                         Padding="5"
                         BackgroundColor="#365271" HeightRequest="40">
              <Label Text="{Binding Key}" FontSize="20" TextColor="White" VerticalOptions="Center"/>
            </StackLayout>
          </ViewCell>
        </DataTemplate>
      </ListView.GroupHeaderTemplate>

      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell >
            <ViewCell.View>
              <StackLayout Spacing="8" Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="FillAndExpand">
                <StackLayout Spacing="10" Padding="5,7,8,7" Orientation="Horizontal" VerticalOptions="Center" HorizontalOptions="FillAndExpand" BackgroundColor="Transparent">
                  <controls:CircleImage Source="{ Binding ProfileImageUrl }" WidthRequest="56" HeightRequest="56"
                    HorizontalOptions="Center" VerticalOptions="Center" Aspect="AspectFill"/>
                  <StackLayout Spacing="0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" BackgroundColor="Transparent">
                    <Label Text="{ Binding ListName }" Style="{StaticResource listItemTitle}" />
                    <Label Text="{ Binding ListDescription }" Style="{StaticResource listItemDescription}" />
                  </StackLayout>
                </StackLayout>
              </StackLayout>
            </ViewCell.View>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>

The ItemsSources property of the ListView is binded to "Model" which is ObservableCollection<T> where T is a BaseModel for all models in my app.

There is a "Refresh" button in Toolbar. When I press the button I clear the Model

Model.Clear();

and populate it again with the server data:

var serverData = ...

                foreach (T item in serverData)
                {
                    if (!Model.Any(i => string.Compare(i.Id, item.Id) == 0))
                    {                        
                        Model.Add(item);
                    }
                }

Now, everytime I refresh the ListView it causes memory leak. I'm using the latest XF version which is 2.3.3.163-pre3
Comment 1 Blazey 2016-10-25 07:44:32 UTC
Is anyone looking at the issue? Are you able to recreate it? It is a really show-stopper bug. We have been working on our app for 10 months. We were about to release the app to my client but with this issue simply we can't. When the bug will be solved?
Comment 2 Mike 2016-10-27 14:29:45 UTC
Sampe peoblem here, also the app turn to slow response. like touching something of the page, it will get touch state more slow just like freeze a little and get touch response.
Comment 3 Mike 2016-11-09 14:40:08 UTC
My feeling is when you "clear" it.  It was not remove the bind bitween ViewModel with the UI.  Then every time OnPropertyChanged happening,  the UI will request too much time the property.

For example: you bind a count with the list item

private string _countStr = "0";
        /// <summary>
        /// Count
        /// </summary>
public string CountStr
{
     get { return _countStr; }
     set
    {
         _countStr = value;
         OnPropertyChanged("CountStr");
     }
}

After you Clear the list binding observable collection many times, when you execute OnPropertyChanged("CountStr") in view model,  you could see the UI will execute too much time :   get { return _countStr; }

Just like all removed items all requesting the updated view model, but even you already clear these old items.

Could you debug and confirm that please @Blazey?  that's what I just found.
Comment 4 Mike 2016-11-09 16:37:03 UTC
About my last comment, I was wrong.  that problem what I said in last comment, not caused by ListView.Clean() method.  it will caused by :

Every time you go to other page and go back to SomePage, or change the App.MainPage = somePage,  or change Master.DetailsPage = SomePage,  you just navigate to the SomePage and the SomePage has a ListView,  it will reload again(no matter the SomePage is new or already exits).   do you understand what I mean?  If not please go to check this:
https://bugzilla.xamarin.com/show_bug.cgi?id=41975



That's a BUG I submit long time ago, but still not fixed.

So If you change the page, and if the Navigated page has a listview,  it will reload.  and that will cause the problem , I call that:  increase Binding View Model problem.

I think that's a problem source.  I hope someone test that too.
Comment 5 Mike 2016-11-09 19:40:46 UTC
After test too much time, I figure out there is a way to temporarily fix this problem.

After you navigate to the page which has ListView(remember no matter change App.MainWindow = x  or  MasterDetail.DetailPage = x  or  Navigation.Push(x)   or  Back to the previous page).  You need to clear the ObservableCollection and add new ViewModel.


Like:


Navigate.Push(some exists page);//  or other way to navigate some exists page.

List<ListItemType> TempList = ListItems.ToList();

ListItems.Clear(); // this is a ObservableCollection which bind with the that page items source.

foreach(ListItemType item in TempList ){


// you must need to create a new ViewModel.
ListItemType newItem = new ListItemType();
newItem.xx = item.XX;

// add the new viewModel to the observable collection again.
ListItem.Add(newItem);

}


But do it in every page which has ListViewItem??  Xamarin is really disaster...

PS: But I can't 100% sure, there are no any memory leak again.
Comment 6 Mike 2016-11-09 20:16:35 UTC
Memory leak still exists.  It will increase the memory, the item will got click after click a few seconds sometimes. slow response.  finally crash.....
Comment 7 Mike 2016-11-10 06:29:26 UTC
As I said on :Comment 4.  The ViewModel binding is definitely the source of the problem.

The Old ViewModel will still keep access by ListViewItem of UI. When we clear the List or Remove that item, still can't fix it.


Is there anyone from Xamarin??
Comment 8 Mike 2016-11-10 17:37:34 UTC
Created attachment 18417 [details]
Sample project and Screenshot
Comment 9 Mike 2016-11-11 06:41:10 UTC
I think the memory leak not only 1 place.
I found there is a more serious memory leak when binding a ViewModel to ListView, after create new page,  if still use the old view model, the memory leak more serious.
I will update a sample project for this,  I hope who fixing this problem will download all sample and test, include the previous sample.
Comment 10 Mike 2016-11-11 06:41:57 UTC
Created attachment 18426 [details]
ViewModel dirty bind memory leak sample project
Comment 11 Jimmy [MSFT] 2016-12-05 23:08:15 UTC
Marking as confirmed since I can see a constant climb in memory usage with the Performance Profiler in Visual Studio when navigating between the pages on both attached repro projects. 

New viewmodel (attachment 18417 [details]): https://www.dropbox.com/s/tgg5s8lzqrjs772/new%20viewmodel.PNG?dl=0

Reusing viewmodel (attachment 18426 [details]): https://www.dropbox.com/s/cqm5u7xlekbh92e/resuse%20viewmodel.PNG?dl=0
Comment 12 Mike 2016-12-13 17:27:09 UTC
Guys I have a temporarily solution, that use Template view replace the List view, but need to send your StackLayout control into your viewmodel, and don't directly operate the Observable collection, just use like this in your view model:

private void Add(Person personData){
YourCollection.Add(personData); // this is observablecollection;

// also put it to the StackLayout witch use TemplateView

TemplatedView view = new TemplatedView();
view.ControlTemplate = viewFindByName;
view.BindingContext = personData;

MyStackLayout.Children.Add(view);
}

Other things like remove, clear, all use same way.



Guys I'm gonna upload the new sample, you could download the all and compare and temporarily use it, ListView full of bug now, I don't have time for fixing yet, If I have I'll try before Xamarin team do.(Looks like they too busy, or not too care UWP)
Comment 13 Mike 2016-12-13 17:27:48 UTC
Created attachment 18873 [details]
TemplateView temporary solution
Comment 14 Mike 2016-12-13 17:30:04 UTC
Please ignore the comment in the TemplateView temporary solution(the latest file which I uploaded) which I display on the top of Page1 and Page2 Labels.
Comment 15 Blazey 2017-01-24 07:29:53 UTC
When this bug will be fixed? I thought it is related to:

https://bugzilla.xamarin.com/show_bug.cgi?id=41271

and should be fixed in 2.3.4-pre1 but the problem still exists in this version.
Comment 16 Johan 2017-02-13 23:05:30 UTC
I posted a similair bug here:
https://bugzilla.xamarin.com/show_bug.cgi?id=52487

I have found that this happens for any ListView that uses RecycleElement even in the simplest of cases.

I really hope Xamarin can take a look at this asap.
Comment 17 KTM450SXF 2017-05-09 18:30:25 UTC
I'm on 2.3.4.231 and I am still seeing a memory leak when I use an ItemTemplate.  When I do not with all other code remaining the same, I do not have a leak.  Here's the pertinent XAML:

<ListView x:Name="srvResults" HasUnevenRows="True" ItemTapped="doItemTapped">
	<ListView.ItemTemplate >
		<DataTemplate>
		<ViewCell>
			<Grid RowSpacing="0">
			<Grid.RowDefinitions>
				<RowDefinition Height="20"/>
				<RowDefinition Height="Auto"/>
				<RowDefinition Height="1"/>
			</Grid.RowDefinitions>
			<Grid.ColumnDefinitions>
				<ColumnDefinition Width="20"/>
				<ColumnDefinition Width="*"/>
			</Grid.ColumnDefinitions>
			<Label Text="{Binding CONTRACT_NUMBER}" HorizontalTextAlignment="Start" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" TextColor="#333333" Style="{Binding IS_DOWNLOADED_STYLE}" />
			<Label Text="{Binding DESCRIPTION}" HorizontalTextAlignment="Start" Grid.Row="1" Grid.Column="1" VerticalOptions="StartAndExpand" TextColor="Navy" Style="{Binding IS_DOWNLOADED_STYLE}" LineBreakMode="TailTruncation"/>
			<BoxView Color="Black" WidthRequest="100" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" HeightRequest="1">
				<BoxView.IsVisible>
				<OnPlatform x:TypeArguments="x:Boolean" iOS="False" Android ="True"/>
				</BoxView.IsVisible>
			</BoxView>
			</Grid>
		</ViewCell>
		</DataTemplate>
	</ListView.ItemTemplate>
</ListView>

If you've found it and I'm not on the right build, please let me know what build I need.  If you haven't found it and the above XAML doesn't help, I'll try to build a sample project that replicates it.
Comment 18 Mikhail Kadan 2017-05-15 10:17:26 UTC
This is really critical as we cannot release a production app, any ETA on this?
Comment 20 Jimmy [MSFT] 2017-06-01 21:32:51 UTC
I am still seeing a continuous increase of memory usage in both projects when using recent Xamarin.Forms versions. 

In the repro project, the issue is demonstrated by switching the MainPage between the two pages. However I also tested with using a NavigationPage to push/pop the pages and the leak is still present.


2.3.6.105   BAD
2.3.5-pre3  BAD
Comment 21 Chris 2017-06-06 16:19:06 UTC
We are experiencing the same on Android with Xamarin forms 2.3.4.247. This bug is preventing us from releasing our app to production. I am all for getting this fixed ASAP.

While we wait I will experiment with removing the ListView control from our application entirely.
Comment 22 MS 2017-07-06 20:14:07 UTC
I think I have also been able to reproduce and isolate this, and it seems there might be a couple aspects related to this.

In the primary aspect, memory is leaking whenever the contents of a Xamarin.Forms ListView are changed.

In the attached test app, there is single “source” list of items, and a subset of these items is display based on filter criteria.
•	With the Xamarin.Forms ListView control (both with a caching strategy of Recycle and a cache strategy of Retain), memory usage continues to grow as the filtering criteria is changed.
•	With the Xamarin.Forms Picker control, memory usage remains constant, even while filtering criteria continues to be changed.

In the attached test app, I have setup these three different control+configuration combinations so that the data binding can be individually enabled or disabled on each control.
•	If either “ListView (Recycle)” or “ListView (Retain)” are enabled, memory consumption continues to grow as additional filter operations are requested
•	If only the Picker control is enabled, memory consumption remains constant, even while additional filter operations are performed.
•	If no controls are enabled, memory consumption remains constant, as in the case when only the Picker control is enabled.

Given the only things changing in the above scenarios is which controls are data-bound, it does not appear that any leaks are occurring it the handling of the underlying IEnumerables and items.


Below are screenshots showing growing memory usage in both the UWP and Android versions of the application.
•	The leak is quite noticeable in the UWP version.
•	With the Android version, while it appears Garbage Collection might be reducing the memory footprint from time to time, it is important to note that the memory usage is never reduced back to earlier levels—over time, baseline memory usage continues to grow. 


In a possibly related aspect, there is a bit of a behavioral difference between the UWP and Android versions of the test app.  In the UWP version of the app, the ListView items are updated as soon as the data bindings are changed, but in the Android version, the ListView items in the Recycle view are not updated until they are redrawn.  If the ListView items were visually updating in real time on a data-bound change like they are in the UWP version, it is possible that the memory leak in the Android version might be even worse.


I have attached a "MemoryLeakTest" zip file with a sample project that reproduces these aforementioned issues.
Comment 23 MS 2017-07-06 20:16:43 UTC
Created attachment 23361 [details]
MemoryLeakTest - Sample Project for Comment 22

Goes with Comment #22
Comment 24 Blazey 2017-07-10 09:21:57 UTC
It has been nearly 9 months since the bug was reported. May I know when can we expect the solution?
Comment 25 David Ortinau [MSFT] 2017-07-11 13:51:08 UTC
@Blazey, it's being working on right now.
Comment 26 tobbe.l.malm 2017-09-27 14:00:36 UTC
Any updates?
Comment 27 Blazey 2017-09-28 07:10:06 UTC
This is funny. Nearly one year has passed and no feedback at all. I still don't know when the issue will be fixed. Please give us some more information instead of waiting, being unsure if it will be fixed at all.
Comment 28 Vivek Suman 2017-11-08 12:06:17 UTC
The same issue we are experiencing while list is showing number of Photos and Application crashes with below Logs:
Incident Identifier: 80161CE4-DBFC-4401-B0D9-816FC2C2625C
CrashReporter Key:   0e3845b16122ba9a68170fe8a4385714b90e31c8
Hardware Model:      iPhone8,1
Process:             DSA.iOS [13126]
Path:                /private/var/containers/Bundle/Application/A6E12BF7-C99A-4004-8A09-0B784049884B/DSA.iOS.app/DSA.iOS
Identifier:          uk.co.nhbc.dsa
Version:             1.4 (1.4)
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           uk.co.nhbc.dsa [2014]


Date/Time:           2017-10-31 15:37:04.1863 +0000
Launch Time:         2017-10-31 15:35:44.1513 +0000
OS Version:          iPhone OS 11.0.3 (15A432)
Baseband Version:    4.00.01
Report Version:      104

Exception Type:  EXC_BAD_ACCESS (SIGABRT)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
VM Region Info: 0 is not in any region.  Bytes before following region: 4295180288
      REGION TYPE                      START - END             [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      UNUSED SPACE AT START
--->  
      __TEXT                 0000000100034000-0000000100070000 [  240K] r-x/r-x SM=COW  ...S.app/DSA.iOS

Triggered by Thread:  0

Application Specific Information:
abort() called

Is there any Fix available for this BUG?

We need a fix as it's critical for our production release.
Comment 29 Christer van der Meeren 2017-11-08 14:19:37 UTC
This might be the same bug, and if that's the case, it might shed some more light on it:

I experience a memory leak wherein if a page has a ListView with a GroupHeaderTemplate, the page is never freed (e.g. when switching it out for another page). If I delete the GroupHeaderTemplate (from the XAML file) and run the app, the page is garbage collected when switching it out. If not, it stays in memory forever.

It does not matter what is inside the GroupHeaderTemplate - I tried with a Label without any bindings, and it still leaks.
Comment 30 Christer van der Meeren 2017-11-08 14:21:11 UTC
I'm using Xamarin.Forms 2.4.0.282, by the way.
Comment 31 David Ortinau [MSFT] 2017-11-09 16:47:47 UTC
Brief update, we are testing a possible fix for this today. This may in fact be multiple issues and require more than one change. Please stay tuned.
Comment 32 E.Z. Hart [MSFT] 2017-11-10 01:49:04 UTC
(In reply to Vivek Suman from comment #28)
> The same issue we are experiencing while list is showing number of Photos
> and Application crashes with below Logs:
> Hardware Model:      iPhone8,1
> Is there any Fix available for this BUG?
> 
> We need a fix as it's critical for our production release.

Vivek,

It appears you're seeing a different bug - this issue (45722) is about a memory leak in ListViews on UWP (Windows). If you're seeing a crash on iOS, please file a new Bugzilla issue and our XF support team will work with you to reproduce it so we can begin working on it.
Comment 33 Christer van der Meeren 2017-11-10 07:03:00 UTC
Note that the memory leak I mentioned in my previous comment is seen in Android, and IIRC iOS too.
Comment 34 E.Z. Hart [MSFT] 2017-11-17 04:05:36 UTC
PR: https://github.com/xamarin/Xamarin.Forms/pull/1285
Comment 35 Rui Marinho 2017-12-05 18:58:52 UTC
Should be fixed on 2.6.0-pre1

Note You need to log in before you can comment on or make changes to this bug.