Android:OutofMemoryError:位图大小超出 VM 预算,没有任何原因我看不到

2024-04-25

我的画廊超过 600x800 像素 JPEG 时遇到内存不足异常。


环境

我一直在使用 Gallery 来处理 600x800 像素左右的 JPG 图像。

由于我的内容可能比图像复杂一些,因此我将每个视图设置为使用 JPG 包装 ImageView 的relativelayout。

为了“加速”用户体验,我有一个 4 个插槽的简单缓存,它预取(在循环程序中)显示图像左侧的 1 个图像和右侧的 1 个图像,并将它们保存在 4 个插槽的 HashMap 中。

该平台

我使用 256 RAM 和 128 堆大小的 AVD,屏幕分辨率为 600x800。 它也会发生在 Entourage Edge 目标上,只不过该设备更难调试。


问题

我遇到了一个例外:

OutofMemoryError: bitmap size exceeds VM budget

当获取第五张图像时就会发生这种情况。我尝试更改图像缓存的大小,但它仍然是相同的。


奇怪的是:不应该是内存问题

为了确保堆限制离我需要的很远,我在开始时定义了一个虚拟的 8MB 数组,并且不引用它,以便立即调度它。它是活动线程的成员,定义如下

static { @SuppressWarnings("unused")
byte dummy[] = new byte[ 8*1024*1024 ]; }    

结果是堆大小接近11MB,而且都是免费的。Note我在它开始崩溃后添加了这个技巧。它可以减少 OutOfMemory 发生的频率。

现在,我正在使用DDMS。就在崩溃之前(崩溃后没有太大变化),DDMS 显示:

ID  Heap Size   Allocated   Free       %Used    #Objects
1   11.195 MB   2.428 MB    8.767 MB   21.69%   47,156  

并在详细表中显示:

Type  Count  Total Size   Smallest   Largest   Median    Average
free  1,536  8.739MB      16B        7.750MB   24B       5.825KB

最大块为7.7MB。然而 LogCat 说:

ERROR/dalvikvm-heap(1923): 925200-byte external allocation too large for this process.

如果您介意中位数和平均值的关系,则可以合理地假设大多数可用块都非常小。然而,有一个足够大的块来容纳位图,它是 7.7M。怎么还是不够呢?

注意:我记录了堆跟踪。看分配的数据量,感觉分配的数据量并没有超过2M。它与 DDMS 的可用内存报告相符。


  • 难道是我遇到了堆碎片之类的问题?
  • 我该如何解决/解决该问题?
  • 堆是否共享给所有线程?
  • 难道是我以错误的方式解释了 DDMS 的读数,并且确实没有 900K 块可以分配?如果是这样,有人可以告诉我在哪里可以看到吗?

多谢

Meymann


我认为你的情况没有什么特别的。只是内存不够。内存中不能有多个 600x800 位图,它们会消耗太多内存。您应该将它们保存到 SD 并按需加载到内存中。我认为这正是你所做的。

您应该注意的一件事:DDMS 显示 java 堆内存消耗。但还有一些本机内存未在 DDMS 中显示。据我所知,位图是在本机内存中创建的。所以 DDMS 只是跟踪这些内存问题的一个糟糕工具。您只需要确保释放内存,垃圾收集器会在您不再需要它们后收集图像。

垃圾收集器按照自己的时间表工作。这就是为什么您应该对不再需要的位图调用 Bitmap.recycle() 方法。此方法准确地释放您用完的本机内存。这样你就可以不依赖GC,并且可以尽快释放最大的一块内存。

首先,您应该确保不会泄漏位图。

这是一个不错的post https://stackoverflow.com/questions/2298208/how-to-discovery-memory-usage-on-my-application-in-android/2299813#2299813关于内存分配,它可以帮助您更深入地挖掘

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android:OutofMemoryError:位图大小超出 VM 预算,没有任何原因我看不到 的相关文章

  • 通过硬件按钮启动 Android 应用程序

    我希望构建一个在单击特定硬件按钮时启动的 Android 应用程序 例如 当我按下音量增大按钮 30 秒时 应用程序必须在不增加音量的情况下启动 我想知道这可能吗 你可以定义一个BroadcastReceiver处理ACTION MEDIA
  • 我可以为 Android Activity 分配“默认”OnClickListener() 吗?

    我有一个 Activity 对于布局中的每个小部件 我调用 setOnClickListener 来分配我的 OnClick 处理程序 在我的 OnClick 处理程序中 我使用 switch 语句根据 View 参数的 ID 为每个按钮执
  • 图像识别后如何在vuforia sdk ImageTarget中显示布局而不是茶壶模型

    如果图像在 qualcomm vuforia sdk 中被识别 我们如何在布局中显示简单的文本 即 Hello 我正在使用 ImageTarget 的 qualcomm vuforia sdk 示例 现在它在识别图像后显示一个茶壶 我是增强
  • Android 从图库中选择图像显示内存错误

    我正在编写一个代码示例 我必须从图库中选择一个图像 该代码正在运行 但是在从图库中选择图像后 我得到了内存不足错误 in my 活动结果时 我可以获得小图像 但大图像会产生问题 这是我的代码 try Uri selectedImageUri
  • Android Wear - 在没有 WearableListenerService 的情况下从 Wear 接收消息?

    我正在开发一款适用于 Android Wear 的应用程序 它可以在手机上启动活动 一切都很好 但我不想依赖手机上不断运行的后台服务来接收此消息 理想情况下 我会让 WearableListenerService 与应用程序同时启动 并保持
  • 相机预览的有效模糊

    到目前为止我尝试过的 将每一帧转换为位图 然后用library https github com wasabeef Blurry并将其放入ImageView这是在相机预览前 显然太慢了 就像1 fps 然后我开始使用渲染脚本这会模糊每一帧
  • 如何在android中使用Mediaprojection库捕获屏幕并转换为mp4文件?

    从 android 5 0 开始 他们提供了媒体投影库来捕获屏幕内容 但他们提供的示例演示应用程序尚不清楚 你可以找到示例应用程序here https github com googlesamples android ScreenCaptu
  • 显示葡萄牙语字符 Android

    我正在开发一个 Android 应用程序 当它应该写 n o 或 cabe a 等单词 例如带有 或 的字符 时 它会写 或 我已经检查过源文件编码 它是UTF 8 看起来 UTF8 被解释为 ISO 8859 x 理论上 你可以提供 ja
  • 删除所有(子)片段的正确方法

    我在父级片段线性布局 fragmentContainer 中动态加载一堆子级片段 然后当用户单击按钮时 我需要将它们全部删除并添加新的 我不知道每次会添加多少碎片 这是我一次性删除所有碎片的方法 LinearLayout ll Linear
  • Android - 在通知栏中使用外部个人资料图像,如 Facebook

    我知道您可以在推送通知参数中发送信息 例如消息 标题 图像 URL 等 Facebook 如何在通知区域中显示您的个人资料图片和消息 我想在通知区域中使用外部图像 因此当您将其下拉时 您会看到带有消息的个人资料图像 现在 我的仅显示可绘制文
  • 为什么大多数 Android 设备不像典型操作系统那样有交换区域?

    现在有 Android 支持交换区域来提高性能吗 出于哪些考虑 大多数 Android 设备放弃了该功能 现在有 Android 支持交换区域吗 Quoting 黛安 哈克伯恩 https groups google com d msg a
  • Android:如何停止监听电话监听器? [复制]

    这个问题在这里已经有答案了 可能的重复 Android 为什么 PhoneCallListener 在活动完成后仍然存在 https stackoverflow com questions 11666853 android why phon
  • 超慢的表格布局性能

    我遇到了糟糕的 TableLayout 性能 我在这里读过一些帖子 谈论同样的事情 Android 动态创建表 性能不佳 https stackoverflow com questions 9813427 android dynamical
  • 如何从 SD 卡中删除文件

    我正在创建一个文件作为电子邮件的附件发送 现在我想在发送电子邮件后删除图像 有没有办法删除文件 我努力了myFile delete 但它没有删除该文件 我在 Android 上使用此代码 因此编程语言是 Java 使用通常的 Android
  • 如何创建克隆重复视图?

    在我的 Android 应用程序中 我想创建重复的ImageButton已经创建的Imagebutton 我想创造新的Imagebutton以编程方式与 XML 文件中已创建的按钮具有相同的宽度 高度 背景 图像源 边距等 简而言之 我想创
  • Android 预安装检测

    我的 Android 应用程序将被预安装 我想继续跟踪预安装的应用程序 为此 我需要以某种方式保存密钥或标志 这意味着该应用程序是预安装的 我会将此密钥添加到后端的每个请求中并对其进行分析 我对此有疑问 有一个问题是关于从 Google P
  • 如何使用Android Invalidate()

    在我的主要活动中 我定义了两个视图和一个菜单 浏览次数 1 自定义视图游戏 2 按钮btn 菜单 1 打开项目用于打开文件 菜单布局在不同的活动中定义 基本上 当主活动启动时 它会绘制没有任何内容的自定义视图和按钮 然后我使用菜单中的 打开
  • Android studio 问题:找不到广告:AdQuality:未指定

    我已经更新了 Android studio 刚刚打开我的项目 我收到以下错误 您能让我知道如何解决这个问题吗 Error A problem occurred configuring project memoryGameCollection
  • 如何在 Android 上设置 Google Drive API?

    我一直在尝试将 Google Drive 功能集成到我的应用程序中 但我无法使用任何内置功能 因此我相信我要么错过了一个步骤 要么做得不正确 我正在遵循官方的 Google 开发者指南 https developers google com
  • 如何在不显示父活动的情况下将一个全屏对话框片段替换为另一个全屏对话框片段?

    我有一个使用单个自定义 DialogFragment 类的活动 它的外观是数据驱动的 因此不同的调用看起来可能相当不同 它是 全屏 即 setStyle DialogFragment STYLE NO FRAME android R sty

随机推荐