我的iPad应用程序在MonoTouch的发展,因为我想避免所有的内存管理的地狱,但它似乎并不如此。 在模拟器上一切正常,但是当我测试我的应用程序在设备上我惊恐地发现,它是由OS一些内存警告后迅速死亡。 我的应用程序是一个简单的图像浏览器,它加载某些PNG图像,并显示他们使用的UIScrollView里面的一些UIViews,得到一个触摸时加载下一个或上。 在模拟器上正常工作。 但在设备上加载和卸载约6-11图像后,开始得到内存警告,然后突然进程被杀死。 我检查了我所有的实例化周期,我加载新的图像之前正确删除所有引用。
于是我开始仪器,开始剖析我的应用程序在iPad上的内存分配。 在那里,我发现现场字节只有大约5-9 MB,正是我的预期,但由于一些奇怪的原因,死者内存分配几乎没有在所有收集到的,因为分配约50 MB(小于5-9 MB的后它是活字节)它被杀死! 这里是仪器剖析我的应用程序会话的截图:
这里是heapshots序列:
也有一些小的泄漏,但我认为他们是没有大到足以成为罪魁祸首。 他们都是48所字节泄漏的strdup从在的iOS 5.1发布时的UIScrollView一个已知的问题:
即使考虑到这似乎确定和分配的现场字节仍处于5 MB的一切,我的应用程序的实际内存被杀害高达50MB的iPad之前呈指数级增长,并达到对iPhone4S的314 MB,所报告的内存监视器:
是否有人可以告诉我,如果有一种方法或工具来发现什么,哪里出了问题? 它是MonoTouch的垃圾收集器的错误吗? 还是有一些对象,我不正确处置? 而我怎么能找到那些与探查? 我检查我的代码了两天,但一切似乎是正确的。
这里是我的装载/实例化/配置周期代码:
void StartImageLoadingThread()
{
tokenSource = new CancellationTokenSource ();
token = tokenSource.Token;
Task task1 = new Task( () => PerformLoadImageTask(token),token);
task1.Start();
}
void PerformLoadImageTask(CancellationToken token)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Task {0}: Cancelling", Task.CurrentId);
return;
}
current_uiimage_A = UIImage.FromFileUncached(file_name);
page_A_image_view.Image = current_uiimage_A;
}
void UnloadImageAFromMemory()
{
page_A_image_view.Image = null;
current_uiimage_A.Dispose();
current_uiimage_A = null;
}
有没有赶上未正确配置的对象的方法? 仪器报道说,现场字节低,泄漏几乎为零,那么为什么死的对象不处置? 即使没有在我的应用程序用于分钟发生,GC似乎并没有使他的工作,即使我明确地把它在我的代码。 我甚至尝试了新的实验垃圾收集器,但它更是雪上加霜,更快地让我的应用程序被杀害。
我找不到任何指导或一步一步引导Xamarin网站上的故障排除内存警告或跟踪不好分配。
任何帮助或建议非常赞赏,谢谢!
更新:我已经减小了尺寸和一些图像和uiviews的分辨率,现在直播字节被丢弃,从9 MB到5 MB顶部,但一些内存警告后,应用仍在杀害不管。
更新2:正如哈维尔建议我已经删除了后台任务,并直接进行调用和内存泄漏消失了! 看来,MonoTouch的垃圾收集器有一个bug,无法收集内存时UIImages分配和布置在不同的线程。 但现在我的应用程序是,当我滚动不亦乐乎反应迟钝,所以我需要找到一个解决方案,以做到在不同的线程! 怎么会呢?