LruCache 内存不足?

Out of memory with LruCache?

最后一行我崩溃了:

InputStream in = new BufferedInputStream(new FileInputStream(file));
byte[] buf = new byte[(int) file.length()];
int numRead = in.read(buf);
final Bitmap bitmap = BitmapFactory.decodeByteArray(buf, 0, numRead); <--- crash

如何避免?

E/dalvikvm-heap: Out of memory on a 31961104-byte allocation.

我明白 31MB 是使用内存的限制吗?使用 LRUCache 存储图像。我设置了 60MB 来存储数据。是不是太多了?

public static int cacheSize = 60 * 1024 * 1024; // 4MiB
    public static LruCache<String, Bitmap> images = new LruCache<String, Bitmap>(cacheSize) {
        protected int sizeOf(String key, Bitmap value) {
            return value.getByteCount();
        }
    };

在我的例子中,一张图片大约有 3MB,我至少需要在缓存中存储 18 张图片。 phone存储60MB的需求这么大吗?

我尝试捕获代码,为什么应用会终止?

How to avoid it?

嗯,您可以使用 decodeStream() 而不是 decodeByteArray() 来帮助您的事业。就目前而言,在解码之前读取整个编码图像是在毫无意义地浪费堆space。

但是,一般来说,您的问题与 LRUCache 无关,而与尝试进行大量 (~30MB) 分配有关。 31961104 字节,作为 Bitmap,相当于 2826px x 2826px 图像。这比大多数 Android 屏幕大得多。对于其中的 one,您可能没有单个连续的堆 space 块,更不用说 18 块了。18 块可能比整个设备占用更多的内存,因为 low-end Android 台设备。

Am I understand good that 31MB is the limit to use memory?

没有。该错误表明您没有足够的可用内存块来存储该图像。

In my case an image is around 3MB

也许在磁盘上。大多数图像文件格式都是压缩的(PNG、JPEG、WebP、GIF 等)。您使用的堆 space 数量基于 解压缩的 大小。正如 njzk3 所指出的,堆 space 基于分辨率(宽度 x 高度,以像素为单位)和位深度(默认情况下每个像素 4 个字节)。

What can I do?

使用较小的位图。

或者,不要将整个位图加载到内存中,而是使用 widgets 可以根据用户平移和缩放手势按需逐步加载图像。