2012-06-18 57 views
3

所以我有一个臭名昭着的OOM错误引起的大位图。但我已经设法解决大部分问题。当我点击后关闭应用程序,然后立即启动应用程序时,剩下的唯一问题就发生了。然后,该应用程序将崩溃给我一个OOM(内存不足)错误。如果我点击回家,这不会发生。安卓应用崩溃内存重启

这是怎么发生的?我的猜测是,GC还没有完成清理工作,现在我开始启动它,而旧数据仍然处于周围。当然这不是一个新的应用程序,所以旧版本和新版本都会受到相同的应用程序内存限制。

在这个问题上的任何投入和可能的解决方案将是伟大的。

什么,我tryed:

位图的所有下载我用:

BitmapFactory.Options op = new Options(); 
op.inPurgeable = true; 
bmImg = BitmapFactory.decodeStream(is,null,op); 

使图像尺寸更小宽x高(以KB大小大致相同) 。 < - 这解决了问题,所以我有一个后备的解决方案,除非有一个人在那里有一个超级的解决方案:)

错误日志的摘录:

06-25 04:29:28.917: E/AndroidRuntime(8819): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:460) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:715) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.content.res.Resources.loadDrawable(Resources.java:1713) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.content.res.TypedArray.getDrawable(TypedArray.java:601) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.widget.ImageView.<init>(ImageView.java:122) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  at android.widget.ImageView.<init>(ImageView.java:112) 
06-25 04:29:28.917: E/AndroidRuntime(8819):  ... 23 more 

编辑: 于是两个事情为我解决这个问题。

  1. 清除我的数据库,并将我的主要活动ondestroy()中的大图像设置为null。
  2. 使大图像变小。

但是,这只是引发同样的基本问题,如果调用onDestroy(),为什么我的活动没有正确关闭,然后打开一个新的?此外,我看到我的活动在关闭后很长一段时间内继续运行。这可能与问题有关吗?我如何查明原因?

编辑2:culprint似乎是我的LruCache。我使用了ondestroy()中未清空的静态lrucache。当应用程序重新启动时,lrucache中的所有图像仍然存在,这会导致问题。我仍然想知道为什么这只是在重新启动时出现问题?当我在关闭它之前回到我的主要活动时,这不应该成为一个问题吗?

+0

这可能是在位图解码的大文件大小,所以你可以尝试这个帖子的位图大尺寸文件解码解决方案:http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue -while-loading-an-image-to-a-bitmap-object/823966#823966欢迎! – Dinesh

回答

0

culprint似乎是我的LruCache。我使用了ondestroy()中未清空的静态lrucache。当应用程序重新启动时,lrucache中的所有图像仍然存在,这会导致问题。我仍然想知道为什么这只是在重新启动时出现问题?当我在关闭它之前回到我的主要活动时,这不应该成为一个问题吗?

不过,我这个问题的临时/永久性修复是清理ondestroy()中的所有静态引用,但也使用较小尺寸的图像。这似乎解决了我所有的问题,因为我也无法找到任何内存泄漏。

1

嘿请我在同一个问题的答案:bitmap size exceeds Vm budget error android

而且还总是试图同时处理位图处理像这样使用最多选项:

 final Options options = new Options(); 
     options.outHeight = (int) scaleHeight; // new smaller height 
     options.outWidth = (int) scaleWidth; // new smaller width 
     options.inScaled = true; 
     options.inPurgeable = true; 

     // to scale the image to 1/8 
     options.inSampleSize = 8; 
     bitmap = BitmapFactory.decodeFile(imagePath, options); 

这可能会解决你的问题。

+0

我已经在inPurgeable中使用。 inSampleSize会降低质量,这不是一个选项。我需要这个图像的大小。 – Warpzit

+0

如果图像的大小非常大,例如2到3 MB,那么加载图像将导致此错误。图像的大小是多少?检查你的代码是否有内存泄漏,这也可能是问题所在。 – Shrikant

+0

mdpi是900 x 900像素和〜93kb,如果图像不是很大,则hdpi会调整为 – Warpzit

2

我遇到了同样的问题,通过强制关闭过程解决了这个问题。这可以通过覆盖onDestroy()来完成。使用这个:

@Override 
public void onDestroy(){ 
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
    List<ActivityManager.RunningAppProcessInfo> pids = am.getRunningAppProcesses(); 
    for (int i = 0; i < pids.size(); i++) { 
     ActivityManager.RunningAppProcessInfo info = pids.get(i); 
     if (info.processName.equalsIgnoreCase(context.getPackageName())) { 
      android.os.Process.killProcess(info.pid); 
     } 
    } 
    super.onDestroy(); 
} 
+0

这可能会起作用,但我想我会尝试查找导致我的应用程序无法正常关闭的参考。 – Warpzit

+0

经过一番阅读(其中包括commonsware)我不会在这个方向去。这可能会导致其他各种麻烦。 – Warpzit

+0

我明白你的顾虑,但我还没找到更好的选择。 –