代码之家  ›  专栏  ›  技术社区  ›  Daniel Benedykt

java.lang.outofmemoryer错误:位图大小超过了虚拟机预算-Android-有多少图像?

  •  4
  • Daniel Benedykt  · 技术社区  · 15 年前

    我正在开发一个Android应用程序,当我四处阅读并为自己学习时,我不能同时在屏幕上显示很多图像,否则我会得到一个例外。

    问题是屏幕上可以同时显示多少图像或多少KB图像或多少布局/图像。

    我知道这不是唯一影响记忆的因素,但我在寻找一个数字,这样我就可以围绕它进行计划。

    谢谢

    丹尼尔


    编辑:

    我刚在android dev网站上找到这个( http://developer.android.com/resources/articles/future-proofing.html )

    要避免的技巧,3:与布局一起出海

    由于视图呈现基础结构的变化,布局中不合理的深度(超过10个左右)或广度(总共超过30个)视图层次结构现在可能导致崩溃。对于过于复杂的布局来说,这总是一个风险,但是你可以认为android 1.5在暴露这个问题上比1.1好。大多数开发人员不需要担心这个问题,但是如果你的应用程序有非常复杂的布局,你需要把它放在一个饮食上。可以使用更高级的布局类(如framelayout和tablelayout)简化布局。

    我想这可能是我的问题。

    当它说“宽泛”时,它是在最后一个层次上说的吗?

    谢谢

    丹尼尔

    5 回复  |  直到 12 年前
        1
  •  7
  •   Carl Veazey    12 年前

    我发现开发Android应用程序最常见的错误之一是

    java.lang.OutOfMemoryError: Bitmap Size Exceeds VM Budget 错误。

    我经常在改变方向后使用大量位图的活动中发现这个错误:活动被破坏,重新创建,布局是由消耗位图可用的虚拟机内存的XML膨胀而来的。

    垃圾收集器没有正确释放上一个活动布局上的位图,因为它们交叉引用了对其活动的引用。经过多次实验,我找到了一个很好的解决这个问题的方法。

    首先,设置 身份证件 XML布局父视图的属性:

        <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:id="@+id/RootView"
         >
         ...
    

    然后,在 onDestroy() 方法,调用UnbindDrawables()方法,将引用传递给父视图,然后执行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
  •  2
  •   Ram kiran Pachigolla    12 年前

    这个答案有两部分

    1)它不是屏幕上有多少图像,而是在完成活动时仔细清理所有内容。

    2) Future-Proofing Your App )

    要避免的技巧,3:与布局一起出海

    由于视图呈现基础结构的变化,布局中不合理的深度(超过10个左右)或广度(总共超过30个)视图层次结构现在可能导致崩溃。对于过于复杂的布局来说,这总是一个风险,但是你可以认为android 1.5在暴露这个问题上比1.1好。大多数开发人员不需要担心这个问题,但是如果你的应用程序有非常复杂的布局,你需要把它放在一个饮食上。可以使用更高级的布局类(如framelayout和tablelayout)简化布局。

    丹尼尔

        3
  •  1
  •   CaseyB    15 年前

    内存量因设备而异,您必须使用的内存量取决于系统当时的其他操作。你最好的办法是,如果你能帮忙的话,你甚至不会接近耗尽系统的内存。你在做什么?你需要屏幕上那么多图像?

        4
  •  1
  •   dharmendra    12 年前

    这取决于手机的堆大小。 因此,如果您的应用程序获得更多堆,那么提供的电话可能会造成问题。

    新一代安卓设备包含。以下是一些

    HTC WildFire(2.2.1)=16MB。
    HTC WildFire S(2.3.5)=20MB。
    HTC Salsa(2.3.3)=20MB。
    HTC愿望(2.3.3)=32MB。
    HTC愿望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

    因此,目前还没有针对它的certan解决方案,但是您可以尝试优化位图的大小。 例如,使用位图后回收它。或者再利用 位图法 脱除 采样器 .

    如果您使用的是模拟器,那么您可以创建一个包含更多堆大小的设备,以在AVD管理器中添加新的额外硬件配置,使VM堆大小等于或大于32。

        5
  •  0
  •   Guillaume TD    15 年前

    我在工作中遇到了同样的问题,但我没有找到解决办法。

    在通过OutOfMemoryException反复调用CreateImage()后,应用程序崩溃。我的猜测是,这不是由活动或上下文泄漏引起的,因为我的应用程序在遇到此问题时始终保持活动状态。

    我试过调试堆,看看是否有什么有用的东西,但是无法访问位图内存空间(我试过g1 1.6,可能是1.5)。所以不知道那里发生了什么(有没有可能的解决办法?).

    我不太确定是什么原因,可能是内存泄漏或内存碎片问题?

    感谢您的帮助!

    谢谢。

    纪尧姆