При сканировании текста в Android Vision происходит утечка памяти в Xamarin.Android

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

Пока процесс запущен, даже если метод 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 ответ

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

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

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

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

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

Другие вопросы по тегам