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:
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?

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 aftercameraSource.Stop();Let me know if that works. Otherwise I'll need repro sample to test it.