繁体   English   中英

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

[英]Out of memory error when using bitmap

我知道这是一个常见问题,但我没有在其他线程中找到适合我的问题的答案。

我在我的应用程序中使用位图来显示用户的个人资料图片。
此外,该应用程序类似于 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)

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM