Xamarin.forms: ImageSource.FromStream retains stream references on UWP

Created on 14 Nov 2019  路  9Comments  路  Source: xamarin/Xamarin.Forms

_This issue has been moved from a ticket on Developer Community._


The following code seems to retain a reference to a MemoryStream indefinitely on UWP:

var stream = photo. GetStream();
var memStream = new MemoryStream();
stream. CopyTo(memStream);
memStream.Position = 0;
ImageControl.Source = ImageSource.FromStream(() => memStream);

I have a scenario where I am receiving video frame by frame and each frame is a single image stream. So I need to update the Source for the Image control frequently (about 30 fps maybe at best). That's a lot of streams.

I created a sample application to reproduce the behavior. It allows you to select multiple photos from your photo library and then animates through them quickly. The sample works on both UWP and Android (I have not tested iOS).

This somewhat contrived example emulates the behavior. Each frame is a MemoryStream and it appears that Xamarin is holding onto a reference to each stream.

An interesting note on UWP is that if I do NOT use the MemoryStream, then there is less memory usage. Perhaps the streams are being cached?

The Android implementation does not appear to have this problem. I can run for minutes and garbage collection regularly keeps memory use low as expected.

I'm using Xamarin Forms 4.3.0.947036.


Original Comments

Visual Studio Feedback System on 11/13/2019, 08:39 PM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.


Original Solutions

(no solutions)

performance 3 feedback-ticket high high impact UWP bug

Most helpful comment

Seeing this issue as well, Forms 4.4.0 SR2 & Microsoft.NETCore.UniversalWindowsPlatform 6.2.9

All 9 comments

Here is a solution that presents the problem on UWP. The Android version does not appear to retain memory.

Steps to reproduce:

  1. Run the UWP program. I suggest x64 unless you want it to just run out of memory in a minute.
  2. Click on the Pick Photos button and choose a few photos.
  3. Observe memory usage rise in a pretty steady upward trend. Alternatively, with an x86 build, observe a crash rather quickly.

ImageSourceFromStreamMemoryUse.zip

@Keith-at-Trimble this is a really interesting one and I have a possible fix over here

https://github.com/xamarin/Xamarin.Forms/tree/fix_8509

It looks like there's a bug in the cancellation logic and the timing on UWP is just right (wrong?) to trigger it.

This await here
https://github.com/xamarin/Xamarin.Forms/blob/87d720c71ec1c8f8fea2daf2105ba4b6689d71f1/Xamarin.Forms.Core/ImageElement.cs#L122

is never completing which is causing a whole bunch of stuff to stay in memory.

Seeing this issue as well, Forms 4.4.0 SR2 & Microsoft.NETCore.UniversalWindowsPlatform 6.2.9

@samhouts Any feedback on why this has gone back on the backlog?

We need to focus on resolving regressions this sprint. This will make a comeback in 168!

Thanks for the update

I've done some tests. Using the repro sample: https://github.com/xamarin/Xamarin.Forms/files/3923175/ImageSourceFromStreamMemoryUse.zip (Thanks @Keith-at-Trimble)

In the sample, use an infinite loop where a MemoryStream is created but is never disposed. After capture 3 images and wait 15 seconds.

Captura de pantalla 2020-05-07 a las 9 30 55
These are the memory usage details:
Captura de pantalla 2020-05-07 a las 9 37 17

Replacing the MemoryStream for this line:
ImageControl.Source = ImageSource.FromStream(() => photo.GetStream());

Captura de pantalla 2020-05-07 a las 9 33 08
(Using the same 3 images and waiting 15 seconds)

Hope this change helps improve, we are going to review ImageSource internally.

@jsuarezruiz

Our scenario was different, we were just assigning one image source in the ViewModel and binding to the view but setting to null in the View and ViewModel (Prism app has nice lifecycle hooks) the page was always retained.

I've moved on to another project so can't share the code but the leak only existed in UWP in a basic scenario.

Was this page helpful?
0 / 5 - 0 ratings