Forum Xamarin.Forms

Bugs? Memory leaks, animation problems and IsVisible

So the title already tells a lot, I started working on a big project in xamarin forms and ran into some issues I can't explain. It think it are bugs, but before reporting them on github I want to be sure I'm not doing stupid things.

I made an example project detailing my problems, you can view the code on:

gitlab.com/TomBruyneelTrisco/xamarintest.git

In it I set the content of a scrollview dynamically by pushing a button. One of the views has a xamarin animation.

Three questions when running the project:

1) None of the views pages is ever released from memory, the destructor is not called and the animation keeps running
2) How do I know if a view is on the screen, IsVisible always returns true
3) The rate parameter in the animation commit function doesn't seem to change anything (evident by removing the debug statement on line 25 in View1.xaml.cs from comment)

To me, all of the points look like bugs. Can somebody clarify what is going wrong in this project?

Thanks

Answers

  • JohnHardmanJohnHardman GBUniversity admin
    edited May 2018

    @tom_prophets

    (1) Pages will not be released until the garbage collector deems that there are no references to those pages. If you search the forum you will find advice (e.g. from @NMackay and @AdamP, amongst others) about how to clean up references. Note that even when the references are gone, the garbage collector will not kick in immediately, so tracking down memory leaks and stray references can be painful. The profiler is your best friend when doing this.
    (2) You are misinterpreting what IsVisible does. IsVisible is a property of a view object, saying whether you want that view to be visible when it is integrated into the UI hierarchy for the page and the page is subsequently rendered. A view object existing, even one in the UI hierarchy for the page, even with IsVisible = true, does not mean that it has been actually been rendered yet. Most people create the UI hierarchy in the constructor of a page (directly in C# or indirectly in XAML), but the page isn't rendered until after the OnAppearing method is called.

  • tom_prophetstom_prophets Member ✭✭

    Thanks, for your answer, I'll try to look into 1 a bit more, but pretty sure I'm not holding any references and I tried manually calling the garbage collector.

    2) So how do I know if a view is on screen if IsVisible is not the correct property?

  • JohnHardmanJohnHardman GBUniversity admin

    @tom_prophets said:
    2) So how do I know if a view is on screen if IsVisible is not the correct property?

    Why do you want to know if a view is on screen? After 3+ years of continuously working with Xamarin.Forms, other than in automated tests built using Xamarin.UITest, I've never had a reason to test that a view has been rendered.

  • tom_prophetstom_prophets Member ✭✭

    @JohnHardman said:

    @tom_prophets said:
    2) So how do I know if a view is on screen if IsVisible is not the correct property?

    Why do you want to know if a view is on screen? After 3+ years of continuously working with Xamarin.Forms, other than in automated tests built using Xamarin.UITest, I've never had a reason to test that a view has been rendered.

    Because the view contains a skiasharp view that is animated. I thought the animation would automatically stop when the view is no longer referenced in a page, but clearly it doesn't. So the animation loop and some calculations concerning it keep running in the background (even when the screen is turned off) consuming cpu cycles and battery.

    Now of course I can in the codebehind of my page call some public function of the view that aborts the animation (like I now do in the example project from this post). And of course that works, I could also use some variable in my ViewModels to abort the animation...But all of that seems like such a hassle :smile: It would be easy to have some method that could be overridden and is executed whenever a view has been added or removed from its parent.

    Ah well, can't have it all I guess.

    I still don't understand why none of the classes is ever freed though, that would also solve the problem.

  • JohnHardmanJohnHardman GBUniversity admin
    edited May 2018

    @tom_prophets said:
    It would be easy to have some method that could be overridden and is executed whenever a view has been added or removed from its parent.

    Unfortunately, AFAIK, there is nothing suitable in Xamarin.Forms - OnParentSet doesn't do it, IsInNativeLayout is intended to be internal to Xamarin and doesn't do it. Without digging deep into the XF source code, my suspicion is that it would require a dependency service that provides access to native o/s functionality.

    I don't use Skiasharp, so don't know whether that provides a suitable API. You might want to re-post the question with Skiasharp in the title.

    @tom_prophets said:
    I still don't understand why none of the classes is ever freed though, that would also solve the problem.

    I haven't looked at your source code, but my guess would be that the animation maintains a reference to the page or to something on the page. Whilst the animation continues, the page cannot be freed up. Of course, there may be other things keeping a reference that stops the page being freed - BindingContext is one of many possibilities. It's worth finding the @NMackay post about the list of things that it's worth nulling in OnPopped. Again, the profiler is the thing to use to track down unexpected references - something that's worth doing regularly as your codebase grows (I left it until my app was already large, and then spent a couple of weeks ensuring that everything could be garbage collected).

  • NickKovalskyNickKovalsky USMember ✭✭✭

    You can create your own IsPageVisible prop in the page viewModel, set it accordingly in the page overrides OnAppearing/OnDissapearing and bind your own animation IsRunning custom property to it. So the anim won't run when page is hidden anyway.

Sign In or Register to comment.