0

After noticing a few crashes on older devices when using TextRecognizer from the library Android.Gms.Vision I decided to profile it using Android Studio and the result was the following:

enter image description here

While the process is running, even if the method ReceiveDetections is empty (no code logic on my side other than instantiating the builder), the memory usage grows really fast, and the app subsequently crashes within one minute. From the profiler I could see that the memory is used in a byte[] variable in the native code.

The interesting fact is that I'm also using the BarcodeDetector from that library, but that's not causing any memory leak. Finally, I also profiled my Xamarin.Android application using the Xamarin profiler, and the Mono code is taking at most a couple of MB, so my code doesn't seem to cause the problem.

I add the code I'm using below:

public class Scanning : Activity, ISurfaceHolderCallback, IProcessor
{
    private SurfaceView surfaceView;
    private CameraSource cameraSource;
    private const int RequestCameraPermissionID = 1001;

    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
    {
        switch (requestCode)
        {
            case RequestCameraPermissionID:
                if (grantResults[0] == Permission.Granted)
                    cameraSource.Start(surfaceView.Holder);
                break;
        }
    }

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        SetContentView(Resource.Layout.Scanning);
        RequestedOrientation = ScreenOrientation.Portrait;

        surfaceView = FindViewById<SurfaceView>(Resource.Id.surfaceView);

        TextRecognizer textRecognizer = new TextRecognizer.Builder(ApplicationContext).Build();

        if (textRecognizer.IsOperational)
        {
            cameraSource = new CameraSource.Builder(ApplicationContext, textRecognizer).Build();

            surfaceView.Holder.AddCallback(this);
            textRecognizer.SetProcessor(this);
        }
    }

    public void SurfaceChanged(ISurfaceHolder holder, [GeneratedEnum] Format format, int width, int height) { }

    public void SurfaceCreated(ISurfaceHolder holder)
    {
        if (CheckSelfPermission(Manifest.Permission.Camera) != Android.Content.PM.Permission.Granted)
        {
            RequestPermissions(new string[]
            {
                Android.Manifest.Permission.Camera
            }, RequestCameraPermissionID);
            return;
        }

        cameraSource.Start(surfaceView.Holder);
    }

    public void SurfaceDestroyed(ISurfaceHolder holder)
    {
        cameraSource.Stop();
    }

    public void ReceiveDetections(Detections detections) { }

    public void Release() { }
}

Am I missing anything on my side, or is it an actual bug of the library?

If yes is there a workaround?

Luca Mozzo
  • 892
  • 2
  • 8
  • 20

1 Answers1

0

MCWs Managed Callable Wrappers (C# code wrapping Android API) might hold reference to some java objects containing other data (Image scanned, text...), so that GC cannot release that memory.

I had similar case in one custom bindings for image recognition.

The solution is to understand which objects might hold references and after they are not needed anymore to manually call GC.Collect().

From this high level view (glance) I would call it in Release() and/or after cameraSource.Stop();

Let me know if that works. Otherwise I'll need repro sample to test it.

moljac
  • 946
  • 9
  • 12
  • To be honest my Huawei has a good memory management and was handling that for a couple of minutes, the problem was with Samsungs (unfortunately people in my team with other devices left already so I can't give you a proper answer). I tried to call the garbage collector after every scan, but the difference is not really noticeable. Xamarin added the issue in the pipeline and hopefully will be fixed https://github.com/xamarin/GooglePlayServicesComponents/projects/1 – Luca Mozzo Dec 18 '18 at 21:59