Android 如何避免OutofMemoryException?

Android 如何避免OutofMemoryException?,android,memory,Android,Memory,我的应用程序中的活动包含片段,这些片段依次包含充满位图数据的listview/GridView。最终用户会耗尽内存,因为以前活动的视图及其片段不会被破坏。所以,当用户到达,比如说,第10个activity-9之前时,会保存大量位图数据 我已经在使用weakrefences了,但是MAT说有些片段的视图引用了Gallery,Gallery反过来又引用了adapter等,所以ImageView和位图都保持活动状态 到目前为止,我已经体验过完全移除碎片,移除适配器。有时它是有效的,但我想知道为什么这会

我的应用程序中的活动包含片段,这些片段依次包含充满位图数据的listview/GridView。最终用户会耗尽内存,因为以前活动的视图及其片段不会被破坏。所以,当用户到达,比如说,第10个activity-9之前时,会保存大量位图数据

我已经在使用weakrefences了,但是MAT说有些片段的视图引用了Gallery,Gallery反过来又引用了adapter等,所以ImageView和位图都保持活动状态

到目前为止,我已经体验过完全移除碎片,移除适配器。有时它是有效的,但我想知道为什么这会如此复杂,是否有更简单的方法来释放/获取而无需太多编码

UPD

我希望能举一个开源应用程序的例子,同样的问题也会受到挑战

UPD2

我的大多数活动的蓝图是:活动包含片段。片段包含了充满ImageView的AbslistView


谢谢。

我建议只把你需要的东西保存在内存中,然后销毁其他所有东西。耗尽所有可用内存是不好的。我会查看活动生命周期并完全理解它,以解决您的问题:

我建议只在内存中保留您需要的内容,并销毁所有其他内容。耗尽所有可用内存是不好的。我会查看活动生命周期并完全理解它,以解决您的问题:

我建议观看谷歌IO 2011演示文稿

您还应该检查应用程序的工作流,以确定何时可以开始销毁旧活动或释放其他资源

您还可以使用来检索进程的内存使用信息,以帮助确定是否需要释放一些旧资源。

我建议您观看Google IO 2011演示文稿

您还应该检查应用程序的工作流,以确定何时可以开始销毁旧活动或释放其他资源


您还可以使用来检索进程的内存使用信息,以帮助确定是否需要释放一些旧资源。

如果不使用所有内存,则很难完成此操作

这需要按需(重新)加载、视图销毁时释放内存以及仔细设计片段和类

有一些关于以这种方式加载图像的有价值的信息

如果您通过某种异步缓存加载程序加载所有图像,请根据需要清除
onviewdestromed
onDetached
上的缓存,并且不要保留对那些位图的其他引用,因为您应该已经消除了大部分问题


生命周期是非常对称的(
onCreate
onDestroy
,…),因此最好将您在生命周期的另一端创建的任何引用设置为空。假设您在生命周期中使用适当的位置,您将免费获得大量内存管理。在您的情况下,您应该检查是否保留了片段,您没有保留对
图像视图
的引用(应该只存在于
onCreateView
->
onDestroyView

如果不使用所有内存,很难完成它

这需要按需(重新)加载、视图销毁时释放内存以及仔细设计片段和类

有一些关于以这种方式加载图像的有价值的信息

如果您通过某种异步缓存加载程序加载所有图像,请根据需要清除
onviewdestromed
onDetached
上的缓存,并且不要保留对那些位图的其他引用,因为您应该已经消除了大部分问题


生命周期是非常对称的(
onCreate
onDestroy
,…),因此最好将您在生命周期的另一端创建的任何引用设置为空。假设您在生命周期中使用适当的位置,您将免费获得大量内存管理。在您的情况下,您应该检查是否保留了片段,如果适配器的getView方法中发生outofmemoryexception,则不保留对
Gallery
ImageView
的引用(只应存在于
onCreateView
->
onDestroyView

<

您可以将通常发生的线路隔离开来,并用一个如下所示的try catch将其包围:

try {
   // load image (or whatever your loadimage is)
    mViewHolder.thumbImage.loadImage();
} catch (OutOfMemoryError e) {
   // clear your image cache here if you have one
   // call gc
   System.gc();
   // load image retry
   mViewHolder.thumbImage.loadImage();
}

这不是世界上最优雅的解决方案,但应该会有所帮助。

如果适配器的getView方法中发生outofmemoryexception

您可以将通常发生的线路隔离开来,并用一个如下所示的try catch将其包围:

try {
   // load image (or whatever your loadimage is)
    mViewHolder.thumbImage.loadImage();
} catch (OutOfMemoryError e) {
   // clear your image cache here if you have one
   // call gc
   System.gc();
   // load image retry
   mViewHolder.thumbImage.loadImage();
}

这不是世界上最优雅的解决方案,但应该会有所帮助。

如果没有看到代码,很难确定。如果您的ImageView保持活动状态,您应该仔细检查适配器中的回收情况。应该只有和你们在屏幕上看到的大致相同数量的视图。我不会回收它们,是吗?我的意思是,如果我回收它们,它将抛出一个关于ImageView缺少的帧的异常。这里有什么解决方法吗?适配器应该始终回收视图。搜索
viewholder
convertview
。假设您在需要时动态创建
Bitmap
s,并且在
ListView
中的每一行仅使用唯一的位图实例,那么如果在
convertview
中找到它们,您应该能够
回收()。但在这种情况下,通过GC进行自动回收对我来说效果很好,因为在显示列表时一次只需要很少的小位图。只是不要为列表中的每一项都设置
ArrayList
或具有图像的等效列表。如果不查看代码就很难确定。如果您的ImageView保持活动状态,您应该再次检查