在使用TextRecognizer
库中的Android.Gms.Vision
时,在旧设备上遇到了一些崩溃之后,我决定使用Android Studio对其进行分析,结果如下:
尽管进程正在运行,但是即使方法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() { }
}
我身边缺少任何东西吗,还是库的实际错误?
是否可以解决?
答案 0 :(得分:0)
MCW的托管可调用包装程序(包装Android API的C#代码)可能包含对包含其他数据(扫描的图像,文本...)的某些Java对象的引用,因此GC无法释放该内存。
在一个用于图像识别的自定义绑定中,我也遇到过类似的情况。
解决方案是了解哪些对象可能包含引用,以及在不再需要它们之后手动调用GC.Collect()
。
从这个高层次的观点(概览),我将其称为Release()
和/或cameraSource.Stop();
之后
让我知道是否可行。否则,我将需要repro示例进行测试。