位图大小超出了VM预算,无法理解原因

问题描述

| 我一直在寻找“位图大小超出VM预算”的问题,但是似乎没有一种解决方案适用于我。我不明白为什么我的程序有时会引发此错误,因为他们使用我的方式似乎并没有引起任何可能的内存泄漏。我的堆栈跟踪指向BitmapFactory.decodeResource()方法。我已经有一张背景图片,可以用来在Canvas上绘制,这就是我一直在初始化它的方式:
Bitmap backgroundImage = BitmapFactory.decodeResource(getResources(),R.drawable.background);
backgroundImage = resizeImage(backgroundImage,w,h);
这就是我一直在使用它的方式:
canvas.drawBitmap(backgroundImage,paint);
我以为在onDestroy方法中放入ѭ2would会有所帮助,但这无济于事。除了XML文件外,程序中没有其他对背景图像资源的引用,但我认为这不会对其产生影响。有人可以向我解释为什么会这样以及如何解决吗? 顺便说一句,此应用程序不涉及屏幕方向更改。     

解决方法

        完成后,您需要释放位图像素。您提到您将其值设置为
null
,但这仅使其符合GC的条件,它没有明确告诉VM您已经用完这些像素,现在是释放它们的好时机。 在将其设置为null之前,只需在位图上调用Bitmap#recycle()即可:
protected void onDestroy() {
    if (this.backgroundImage != null) {
        this.backgroundImage.recycle();
        this.backgroundImage = null;
    }
}
此外,您可能会在
resizeImage()
方法中浪费资源,而您并未为此提供代码。在解码时对位图进行适当的下采样,而不是加载完整大小的位图,然后从那里进行缩小,效率要高得多。 一般技术是将BitmapFactory.decodeResource()的3个参数版本与BitmapFactory.Options#inJustDecodeBounds一起使用以进行第一次遍历,以便获得Bitmap的宽度/高度(尽管在您的情况下,因为它来自应用程序的资源,甚至没有理由甚至不必这样做。.但我还是要解释一下);然后根据目标大小确定合适的采样大小,然后再次对位图进行解码。这通常会减少内存使用,特别是对于非常大的图像(例如,将“ 6”设置为2时),它会解码完整尺寸的位图,但只会为原始尺寸的一半的位图分配足够的内存,从而缩小处理)。