Dan*_*ykt 157 memory android memory-leaks bitmap out-of-memory
我开发了一个在Android上使用大量图像的应用程序.
该应用程序运行一次,填满屏幕上的信息(Layouts,Listviews,Textviews,ImageViews,等)和用户读取的信息.
没有动画,没有特效或任何可以填充内存的东西.有时候抽屉可以改变.有些是android资源,有些是保存在SDCARD文件夹中的文件.
然后用户退出(该onDestroy方法被执行并且app由VM保持在内存中)然后在某个时刻用户再次进入.
每次用户进入应用程序时,我都可以看到内存越来越多,直到用户获得java.lang.OutOfMemoryError.
那么处理许多图像的最佳/正确方法是什么?
我应该把它们放在静态方法中,这样它们就不会一直装载吗?我是否必须以特殊方式清洁布局或布局中使用的图像?
hp.*_*oid 96
我发现开发Android应用程序的最常见错误之一是"java.lang.OutOfMemoryError:Bitmap Size Exceeds VM Budget"错误.我在更改方向后使用大量位图的活动经常发现此错误:活动被销毁,再次创建,布局从消耗可用于位图的VM内存的XML中"膨胀".
前一个活动布局上的位图未被垃圾收集器正确解除分配,因为它们已经交叉引用了它们的活动.经过多次实验,我发现了一个很好的解决方案.
首先,在XML布局的父视图上设置"id"属性:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/RootView"
>
...
Run Code Online (Sandbox Code Playgroud)
然后,在onDestroy() Activity 的方法上,调用unbindDrawables()方法将引用传递给父View,然后执行System.gc().
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.RootView));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
Run Code Online (Sandbox Code Playgroud)
此unbindDrawables()方法以递归方式探索视图树,并且:
Tre*_*hns 70
听起来你有内存泄漏.问题不在于处理许多图像,而是当您的活动被破坏时,您的图像不会被解除分配.
很难说为什么没有看你的代码.但是,本文提供了一些可能有用的提示:
http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html
特别是,使用静态变量可能会使事情变得更糟,而不是更好.您可能需要添加在应用程序重绘时删除回调的代码 - 但同样,这里没有足够的信息可以肯定地说.
ddm*_*nko 10
要避免此问题,您可以Bitmap.recycle()在null-ing Bitmap对象之前使用本机方法(或设置其他值).例:
public final void setMyBitmap(Bitmap bitmap) {
if (this.myBitmap != null) {
this.myBitmap.recycle();
}
this.myBitmap = bitmap;
}
Run Code Online (Sandbox Code Playgroud)
接下来你可以改变myBitmapw/o调用,System.gc()如:
setMyBitmap(null);
setMyBitmap(anotherBitmap);
Run Code Online (Sandbox Code Playgroud)
小智 7
此说明可能有所帮助:http: //code.google.com/p/android/issues/detail?id = 8488#c80
"快速提示:
1)永远不要自己调用System.gc().这已在此处作为修复传播,但它不起作用.不要做.如果您在我的解释中注意到,在获取OutOfMemoryError之前,JVM已经运行了垃圾收集,因此没有理由再次执行一次(它会减慢您的程序速度).在活动结束时执行一项操作就是解决问题.它可能会使位图更快地放在终结器队列中,但没有理由你不能简单地在每个位图上调用recycle.
2)总是在你不再需要的位图上调用recycle().至少,在您的活动的onDestroy中,通过并回收您正在使用的所有位图.此外,如果您希望更快地从dalvik堆中收集位图实例,则清除对位图的任何引用都没有什么坏处.
3)调用recycle()然后System.gc()仍然可能无法从Dalvik堆中删除位图.不要关心这个.recycle()完成了它的工作并释放了本机内存,它只需要一些时间来完成我前面概述的步骤,实际上从Dalvik堆中删除了位图.这不是什么大问题,因为大量本机内存已经免费!
4)始终假设框架中存在最后的错误.达尔维克正在做它应该做的事情.它可能不是您所期望的或您想要的,但它的工作原理."
我有同样的问题.经过一些测试后,我发现这个错误出现在大图像缩放中.我减少了图像缩放,问题就消失了.
PS起初我尝试在不缩小图像的情况下缩小图像尺寸.这并没有阻止错误.
小智 5
以下几点对我帮助很大.可能还有其他要点,但这些非常重要:
| 归档时间: |
|
| 查看次数: |
114845 次 |
| 最近记录: |