При сканировании текста в Android Vision происходит утечка памяти в Xamarin.Android - PullRequest
0 голосов
/ 17 декабря 2018

Заметив несколько сбоев на старых устройствах при использовании TextRecognizer из библиотеки Android.Gms.Vision, я решил профилировать его с помощью Android Studio, и в результате получилось следующее:

enter image description here

Во время выполнения процесса, даже если метод ReceiveDetections пуст (с моей стороны нет никакой логики кода, кроме создания экземпляра компоновщика), использование памяти растет очень быстро, и приложение впоследствии падает водна минута.Из профилировщика я мог видеть, что память используется в переменной byte[] в собственном коде.

Интересно то, что я также использую BarcodeDetector из этой библиотеки, но это не вызываетлюбая утечка памяти.Наконец, я также профилировал свое приложение Xamarin.Android, используя профилировщик Xamarin, и код Mono занимает максимум пару МБ, поэтому мой код, похоже, не вызывает проблемы.

Я добавляю кодЯ использую ниже:

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 голосов
/ 18 декабря 2018

MCWs Managed Callable Wrappers (обертывание кода C # для Android API) может содержать ссылку на некоторые объекты Java, содержащие другие данные (изображение отсканировано, текст ...), так что GC не может освободить эту память.

У меня был похожий случай в одних пользовательских привязках для распознавания изображений.

Решение состоит в том, чтобы понять, какие объекты могут содержать ссылки, и после того, как они больше не нужны для ручного вызова GC.Collect().

Из этого взгляда высокого уровня (взгляд) я бы назвал его в Release() и / или после cameraSource.Stop();

Дайте мне знать, если это работает.В противном случае мне понадобится образец репро, чтобы проверить его.

...