Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report for Bug 21454 on
Developer Community or GitHub if you have new
information to add and do not yet see a matching new report.
If the latest results still closely match this report, you can use the
In special cases on GitHub you might also want the comments:
GitHub Markdown with public comments
The list view performance is very slow in both of the attached test projects, one which uses the view holder patter and one which does not.
This appears to be due to a very high greg count and it seems that the grefs are not being released properly when the GetView method exits.
1. Load either test project.
2. Launch on device/emulator
3. Sroll listview.
Expected result: a smooth scrolling list view.
Actual result: a virtually unusable list view.
See case file in private comment above for more information and steps the developer has taken to try to track down the issue.
Created attachment 7428 [details]
Test Project with View Holder Pattern
PS, in the test project with the view holder pattern, I also tried to use a layout file instead of creating a layout programmatically. This did seem to help a bit, but not very much.
Besides the performance issue, our main concern is gref consumption. We cannot use the "ViewHolder" approach/pattern because of the number of grefs that would be held (for a ListView containing 50 columns of TextViews with, let's say, 10 rows of visible data, we would see the potential for 500 TextViews. When you take into account our need to resize TextViews programmatically based on data that appears in the column (we want to size the TextViews to be as wide as the widest value), the gref count grows even larger due to needing to allocate LayoutParameter objects and assign them to each TextView's LayoutParameters member when allocating new TextViews for inclusion in the ListView as a result of seeing GetView()'s convertView member being null.
In our case, the ListView is list of horizontal LinearLayouts, with each layout consisting of TextViews, one for each column.
To reduce the number of grefs that are actively held our ListView implementation, we have chosen to invoke Dispose() the TextView references obtained while in GetView(), whether instantiated due to the convertView being empty, or as a result of invoking FindViewById() against convertView (we only allocate a new LinearLayout and new TextViews for the row when GetView()'s convertView member is null - otherwise we invoke FindViewById() against the LinearLayout passed to us to get a reference to each TextView in the LinearLayout). Our concerns with this approach, however, include a) is it a safe to invoke Dispose() in this way, and b) why do we need to invoke Dispose() explicitly in the first place - why doesn't leaving the scope in which a TextView reference (gref) has been instantiated either through a call to "new TextView(context)' or "FindViewById(Resource.Id.XXX)" cause the gref to be disposed of automatically.
Through additional testing, we found that we can also dispose of the TextView's LayoutParameters member which we either instantiate in GetView() if convertView is null, or get back as a result of invoking FindViewById(), given that we instantiate one before adding the view to the LinearLayout (see the sample project posted by Jon), without any apparent adverse affects. Invoking FindViewById() against the LinearLayout passed to us by GetView() via its convertVIew parameter when not null returns a TextView with its LayoutParameters member assigned. By calling Dispose() on the TextView's LayoutParameters member before invoking Dispose() on the TextView reference results in even more gref savings. This, however, poses another question - why doesn't disposing of the TextView also dispose of the TextView's members, the LayoutParameters member in this case?
Again, while we are concerned with the poor scrolling quality, we are more concerned with gref consumption, why grefs are not being disposed of automatically, and whether our explicit use of Dispose() from within GetView() is a safe thing to do, presuming that we are not keeping a reference to the given gref someplace else.
I had posted another question to Jon as well, in that we recognize that invoking FindViewById() will return a pre-existing gref if one exists, instead of allocating a new one. However, if you invoke Dispose() on one such gref while another exists, the iIspose() ends up affecting both references. What surprised me about this is that Xamarin does not seem to maintain a reference count inside each gref that would tell it if a call to Dispose() should really dispose of the gref.
Anyway, Jon has my personal credentials if you would like to contact me by email or phone if you need additional information.
Thanks in advance for looking at this case.
I tried to reproduce this issue with the attached sample and I am also getting the same behavior.
When I try to scroll the listview I observed that listview is not scrolling smoothly. I have checked both the attached project one which is not using view holder pattern and another on which is using the view holder pattern.
I have checked this issue on both device and emulator and I am getting the same behavior on both device and emulator.
Mac OS X 10.9.3
Xamarin Studio: 5.1.4 (build 0)
Release ID: 501040000
Git revision: 7d45bbe2ee22625f125d0c52548524f02d005cca
Build date: 2014-07-14 12:15:53-04
Xamarin addins: c78f1d88e57baa928aeee1484d96e6f8edf8de33
Again, please also consider our concerns with grefs and having to explicitly dispose of them (i.e., the TextView and LayoutParameter references in my original example), instead of Xamarin disposing of them automatically upon leaving the scope of a given block or method.