【问题标题】:bitmap size exceeds VM budget java.lang.OutOfMemoryError: bitmap size exceeds VM budget位图大小超出 VM 预算 java.lang.OutOfMemoryError:位图大小超出 VM 预算
【发布时间】:2012-08-19 16:45:21
【问题描述】:

我知道这个问题已经在这个论坛上被问过很多次了,但我仍然无法得到完美的答案来解决这个问题。

在我的应用程序中,我使用 3 种不同尺寸的相同图像:小、中、大。

当我多次使用这张图片时,我得到了这个错误。

08-24 11:08:55.994: E/ImageLoader(636): bitmap size exceeds VM budget
08-24 11:08:55.994: E/ImageLoader(636): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
08-24 11:08:55.994: E/ImageLoader(636):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
08-24 11:08:55.994: E/ImageLoader(636):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:459)
08-24 11:08:55.994: E/ImageLoader(636):     at com.nostra13.universalimageloader.core.ImageDecoder.decode(ImageDecoder.java:75)
08-24 11:08:55.994: E/ImageLoader(636):     at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeWithOOMHandling(LoadAndDisplayImageTask.java:161)
08-24 11:08:55.994: E/ImageLoader(636):     at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:148)
08-24 11:08:55.994: E/ImageLoader(636):     at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:104)
08-24 11:08:55.994: E/ImageLoader(636):     at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:58)
08-24 11:08:55.994: E/ImageLoader(636):     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
08-24 11:08:55.994: E/ImageLoader(636):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-24 11:08:55.994: E/ImageLoader(636):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-24 11:08:55.994: E/ImageLoader(636):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
08-24 11:08:55.994: E/ImageLoader(636):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
08-24 11:08:55.994: E/ImageLoader(636):     at java.lang.Thread.run(Thread.java:1096)

任何人都可以帮助解决它..我已经搜索了很多相同的问题,但我仍然没有得到这样的解决方案..

这就是为什么我必须在凌晨四点写这个问题。

我正在等待肯定的答复..

谢谢。

【问题讨论】:

  • 您能提供一些代码吗?您已经尝试过哪些图像缓存/加载的确切逻辑?
  • 其实我正在使用universal-image-loader-1.5.4.jar 文件来加载我的图片..
  • 首先阅读 Android 开发人员培训here,了解如何处理位图。
  • 您是否每次使用时都在为图像重新创建位图?或者您只分配一次并重复使用它们?如果是前者,你有没有调用 bitmap.recycle() ?
  • .memoryCache(new WeakMemoryCache()) 在配置 ImageLoaderConfiguration 时使用它

标签: android


【解决方案1】:

这是图像的常见问题。 Android 为每个应用程序提供了一定数量的空间。在没有缩小尺寸的情况下拍摄的图像往往会导致这个问题。最好的解决办法是

BitmapFactory.Options options = new BitmapFactory.Options();

options.inSampleSize = 8;(此处使用值作为 2 的幂以获得最佳解决方案)

并在解码时将它们传递给位图

Bitmap bm = BitmapFactory.decodeStream(<input image file>, null, options);

【讨论】:

  • 好的..但是因为我使用jar文件进行图像加载..所以图像解码过程在那个jar文件中。
  • 我想知道我在使用那个 jar 文件时遇到的这个问题?
  • 是的,jar 文件可能是这里的问题,它可能不会对图像大小进行下采样以避免内存不足问题
【解决方案2】:

我认为你可以使用失败重试机制来解决这个问题。

Like : 尝试正常加载图像,如果失败,从 catch 块,尝试使用 BitmapConfig (Bitmap.Config.ARGB_4444) 以降低质量加载它,如果再次失败,尝试以更低质量加载它(Bitmap.Config.ALPHA_8)。我也遇到了同样的问题,现在这个方法对我有用。

Bitmap imageBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = false; 
options.inPurgeable = true;
options.inInputShareable = true; 
options.inTempStorage = new byte[32 * 1024];
options.inPreferredConfig = config;//Bitmap.Config.ARGB_4444 or Bitmap.Config.ALPHA_8 when failed  
options.inSampleSize = 1;
imageBitmap = BitmapFactory.decodeFile(bitmapPath, options);

【讨论】:

  • 你好,你说的是哪种方法?
  • 我已经包含了上面的代码。将代码放在 try catch 块中,然后从 catch 部分尝试以较低质量再次解码。
【解决方案3】:

您可以使用此方法对位图进行解码:

public static Bitmap loadBitmap() {
    FileInputStream fis = null;
    Bitmap bitmap = null;

    BitmapFactory.Options option = new BitmapFactory.Options();
    option.inDither = false;
    option.inPurgeable = true;
    option.inInputShareable = true;
    option.inTempStorage = new byte[32 * 1024];
    option.inPreferredConfig = Bitmap.Config.RGB_565;

    try {
        fis = IOHelper.openInputStream(); //get the picture's FileInputStream
        FileDescriptor fd = fis.getFD();
        bitmap = BitmapFactory.decodeFileDescriptor(fd, null, option);
    } catch (IOException e) {

    } finally {
        IOHelper.closeQuietly(fis);
    }
    return bitmap;
}

【讨论】:

    【解决方案4】:
    Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
    

    这意味着设备内存不足,正在被强制关闭。

    现在,既然您说多次使用图像时会出现错误,我相信您并没有释放资源。位图有时会占用大量空间,如果您将它们保存在内存中,如果设备出现 OOM,我不会感到惊讶。不同的设备有不同的内存规格,运行几次后就会填满内存。

    所以,我的建议是清除位图和您用于临时目的的其他存储。

    如果这仍然不能解决您的问题,请将代码发布到您处理图像的位置,我们将尝试查看是否有更节省内存的方式来处理您正在做的事情。

    祝你好运!

    【讨论】:

      【解决方案5】:

      这是一个老问题,但我最终浪费了一整天时间尝试使用出色的 UIL 修复旧设备上的图像内存问题。这些答案都不是 UIL 特有的,我的解决方案最终来自于偶然发现 Nostra 自己回答的这个问题:

      How can I resize a picture before displaying it in a view with Android Universal Image Loader?

      这里的 ma​​xImageWidthForMemoryCache 和高度值对我来说非常重要。我正在下载并显示大约屏幕大小的图像,并将其放置在屏幕宽度和高度的图像视图中,因此实际上没有发生任何缩放。这对于我的 2.3 手机来说太大了,将尺寸减半帮助很大,几乎没有明显的图像退化。

      【讨论】:

        猜你喜欢
        • 2011-04-26
        • 1970-01-01
        • 2010-12-29
        • 2011-07-27
        相关资源
        最近更新 更多