java.lang.OutOfMemoryError:位图大小超出 VM 预算 - android - 多少图像?
Posted
技术标签:
【中文标题】java.lang.OutOfMemoryError:位图大小超出 VM 预算 - android - 多少图像?【英文标题】:java.lang.OutOfMemoryError: bitmap size exceeds VM budget - android - how many images? 【发布时间】:2010-12-29 15:17:47 【问题描述】:我正在开发一个 android 应用程序,当我阅读并为自己学习时,我不能同时在屏幕上显示很多图像,否则会出现异常。
问题是我可以在屏幕上同时拥有多少张图片或多少 KB 的图片或多少个布局/图片。
我知道这不是唯一影响记忆的事情,但我正在寻找一个数字,以便我可以围绕它进行计划。
谢谢
丹尼尔
编辑:
我刚刚在 android 开发网站 (http://developer.android.com/resources/articles/future-proofing.html) 上找到了这个
要避免的技巧,#3:过度使用布局
由于视图渲染基础架构的变化,布局中不合理的深度(超过 10 个左右)或过宽(总共超过 30 个)视图层次结构现在可能会导致崩溃。对于过于复杂的布局来说,这总是存在风险,但您可以认为 Android 1.5 在暴露这个问题方面比 1.1 更好。大多数开发人员无需担心这一点,但如果您的应用程序布局非常复杂,则需要节食。您可以使用更高级的布局类(如 FrameLayout 和 TableLayout)来简化布局。
我想这可能是我的问题。
当它说'broad'时,它是在说最后一层吗?
谢谢
丹尼尔
【问题讨论】:
相关:***.com/questions/1949066/… 非要问,买不起。 【参考方案1】:我发现开发 Android 应用程序的最常见错误之一是
java.lang.OutOfMemoryError: Bitmap Size Exceeds VM Budget
错误。
我经常在更改方向后使用大量位图的 Activity 上发现此错误:Activity 被销毁,再次创建,并且布局从 XML 中“膨胀”,消耗了可用于位图的 VM 内存。
前一个活动布局上的位图没有被垃圾收集器正确释放,因为它们交叉引用了它们的活动。经过多次实验,我找到了一个非常好的解决这个问题的方法。
首先,在 XML 布局的父视图上设置 id 属性:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:id="@+id/RootView"
>
...
然后,在 Activity 的 onDestroy()
方法上,调用 unbindDrawables() 方法,将引用传递给父 View,然后执行 System.gc()
@Override
protected void onDestroy()
super.onDestroy();
unbindDrawables(findViewById(R.id.RootView));
System.gc();
private void unbindDrawables(View view)
if (view.getBackground() != null)
view.getBackground().setCallback(null);
if (view instanceof ViewGroup)
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
unbindDrawables(((ViewGroup) view).getChildAt(i));
((ViewGroup) view).removeAllViews();
这个 unbindDrawables() 方法递归地探索视图树并且:
移除所有背景可绘制对象的回调 删除每个视图组上的子项【讨论】:
你的逻辑帮我解决了内存不足的异常......非常感谢分享这么棒的逻辑【参考方案2】:这个答案有两部分
1) 不是屏幕有多少图像,而是在完成活动时小心清理所有内容
2) (Future-Proofing Your App
)
要避免的技巧,#3:过度使用布局
由于视图渲染基础架构的变化,布局中不合理的深度(超过 10 个左右)或过宽(总共超过 30 个)视图层次结构现在可能会导致崩溃。对于过于复杂的布局来说,这总是存在风险,但您可以认为 Android 1.5 在暴露这个问题方面比 1.1 更好。大多数开发人员无需担心这一点,但如果您的应用程序布局非常复杂,则需要节食。您可以使用更高级的布局类(如 FrameLayout 和 TableLayout)来简化布局。
丹尼尔
【讨论】:
【参考方案3】:内存量因设备而异,您必须使用的内存量取决于系统当时正在执行的其他操作。如果可以提供帮助,最好的办法就是不要让系统内存不足。你在做什么需要屏幕上显示这么多图像?
【讨论】:
是的,我在屏幕上有很多图像,它一次又一次地崩溃如何解决它。【参考方案4】:这取决于手机的 HEAP 大小。 因此,如果您的应用程序获得的堆比提供的电话多,那么它可能会产生问题。
新一代安卓设备包含。这里是一些列表
HTC Wildfire (2.2.1) = 16MB。 HTC Wildfire S (2.3.5) = 20MB。 HTC 莎莎 (2.3.3) = 20MB。 HTC Desire (2.3.3) = 32MB。 HTC Desire S (2.3.5) = 32MB。 三星 Galaxy S GT-I9000 (2.2) = 48MB。 三星 Galaxy R GT-I9103 (2.3.5) = 64MB。 三星 Galaxy Y GT-S5360 (2.3.5) = 64MB
因此没有特定的解决方案,但您可以尝试优化位图大小。 例如在使用后回收位图。或使用从 sampleSize 中提取的 bitmapFectory 制作另一个。
如果您使用的是模拟器,那么您可以创建一个包含更多堆大小的设备,以便在您的 avd 管理器中将新的额外硬件配置添加为 VM 堆大小 = 32 或更高。
【讨论】:
那只适用于模拟器,不适用于真机,所以不是解决方案以上是关于java.lang.OutOfMemoryError:位图大小超出 VM 预算 - android - 多少图像?的主要内容,如果未能解决你的问题,请参考以下文章