使用位图时出现内存不足错误

时间:2015-10-26 13:47:22

标签: java android memory bitmap out

我知道这是一个常见的问题,但我没有在其他主题中找到问题的正确答案。

我在应用程序中使用位图来显示用户的个人资料图片 此外,该应用程序就像Instagram,所以有一个页面显示数据库中的图片 问题是当我在活动之间重定向时,我经常会遇到 - “遗憾的是应用程序停止了”。

在日志中我发现了“内存不足”错误 我认为这是因为我应该通过回收位图来清理内存。

我不知道为什么它不起作用。
请帮助我如何以不会出错的方式使用位图。

以下是打印位图的页面的一部分。 我在数据库中有行 我使用while并运行所有行。
我制作了新的ImageViews,TextViews,我就像Instagram一样打印它们。

在这里,您可以看到我如何每行打印图片:

ImageView v = new ImageView(this);
b2 = BitmapFactory.decodeByteArray(res4.getBlob(1), 0, res4.getBlob(1).length);
v.setImageBitmap(b2);
v.setId(count + 1);
p = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
p.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
p.width = width;
p.setMargins(0, 0, 0, 20);
p.addRule(RelativeLayout.BELOW, count);
rl.addView(v, p);

我应该在哪里回收位图?这是解决方案吗? 这是显示“oom error”的日志的一部分:

10-05 18:53:31.184 16093-16093/com.example.user.instamath2 W/CursorWindow﹕ Window is full: requested allocation 1423987 bytes, free space 1241748 bytes, window size 2097152 bytes
10-05 18:53:31.201 16093-16093/com.example.user.instamath2 D/dalvikvm﹕ between the previous GC alloc 4461K
10-05 18:53:31.227 16093-16093/com.example.user.instamath2 I/dalvikvm-heap﹕ Clamp target GC heap from 132.368MB to 128.000MB
10-05 18:53:31.227 16093-16093/com.example.user.instamath2 D/dalvikvm﹕ GC_FOR_ALLOC freed 1229K (1749), 3% free 126908K/130816K, paused 25ms, total 25ms
10-05 18:53:31.227 16093-16093/com.example.user.instamath2 I/dalvikvm-heap﹕ Forcing collection of SoftReferences for 3149840-byte allocation
10-05 18:53:31.227 16093-16093/com.example.user.instamath2 D/dalvikvm﹕ between the previous GC alloc 0K
10-05 18:53:31.257 16093-16093/com.example.user.instamath2 I/dalvikvm-heap﹕ Clamp target GC heap from 132.360MB to 128.000MB
10-05 18:53:31.257 16093-16093/com.example.user.instamath2 D/dalvikvm﹕ GC_BEFORE_OOM freed 9K (44), 3% free 126899K/130816K, paused 31ms, total 31ms
10-05 18:53:31.257 16093-16093/com.example.user.instamath2 E/dalvikvm-heap﹕ Out of memory on a 3149840-byte allocation.
10-05 18:53:31.258 16093-16093/com.example.user.instamath2 I/dalvikvm﹕ "main" prio=5 tid=1 RUNNABLE
10-05 18:53:31.258 16093-16093/com.example.user.instamath2 I/dalvikvm﹕ | group="main" sCount=0 dsCount=0 obj=0x41d00de0 self=0x41cee638
10-05 18:53:31.258 16093-16093/com.example.user.instamath2 I/dalvikvm﹕ | sysTid=16093 nice=0 sched=0/0 cgrp=default handle=1074549128
10-05 18:53:31.258 16093-16093/com.example.user.instamath2 I/dalvikvm﹕ | state=R schedstat=( 2032092377 14250700 588 ) utm=164 stm=39 core=2
10-05 18:53:31.258 16093-16093/com.example.user.instamath2 I/dalvikvm﹕ at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
10-05 18:53:31.258 16093-16093/com.example.user.instamath2 I/dalvikvm﹕ at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:529)

1 个答案:

答案 0 :(得分:1)

因此,根据文档,recycle()不需要正常调用,因为如果您的引用超出范围,JVM将无论如何都会回收它。

  

释放与此位图关联的本机对象,并清除对像素数据的引用。这不会同步释放像素数据;如果没有其他引用,它只是允许它被垃圾收集。位图标记为" dead",这意味着如果调用getPixels()或setPixels(),它将抛出异常,并且不会绘制任何内容。此操作无法撤消,因此只有在您确定位图没有进一步用途时才应调用此操作。这是一个高级调用,通常不需要调用,因为正常的GC进程将在没有更多对此位图的引用时释放此内存。

但是在您与我们分享的代码段中,我们不清楚b2是否超出范围,因此JVM可能永远不会垃圾收集它。您在活动生命周期中的哪个位置分配位图?你怎么用b2做的?

如果您想显式回收位图,我会将其作为stop()或destroy()生命周期事件的一部分。只需确保您在相应的生命周期事件中分配(即分别为start()或create())。