Android Vision Text扫描会泄漏Xamarin.Android中的内存

时间:2018-12-16 23:45:23

标签: android xamarin.android ocr android-vision

在使用TextRecognizer库中的Android.Gms.Vision时,在旧设备上遇到了一些崩溃之后,我决定使用Android Studio对其进行分析,结果如下:

enter image description here

尽管进程正在运行,但是即使方法ReceiveDetections为空(除了实例化构建器之外,我这一边也没有代码逻辑),内存使用量确实增长很快,并且该应用程序随后在一分钟内崩溃。从事件探查器中,我可以看到在本机代码的byte[]变量中使用了内存。

有趣的事实是,我也在使用该库中的BarcodeDetector,但这不会引起任何内存泄漏。最后,我还使用Xamarin探查器对Xamarin.Android应用程序进行了配置,Mono代码最多占用了几MB,因此我的代码似乎不会引起问题。

我在下面添加我正在使用的代码:

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() { }
}

我身边缺少任何东西吗,还是库的实际错误?

是否可以解决?

1 个答案:

答案 0 :(得分:0)

MCW的托管可调用包装程序(包装Android API的C#代码)可能包含对包含其他数据(扫描的图像,文本...)的某些Java对象的引用,因此GC无法释放该内存。

在一个用于图像识别的自定义绑定中,我也遇到过类似的情况。

解决方案是了解哪些对象可能包含引用,以及在不再需要它们之后手动调用GC.Collect()

从这个高层次的观点(概览),我将其称为Release()和/或cameraSource.Stop();之后

让我知道是否可行。否则,我将需要repro示例进行测试。