代码之家  ›  专栏  ›  技术社区  ›  Samuh

Android中的位图

  •  29
  • Samuh  · 技术社区  · 15 年前

    我有几个关于位图对象和内存及其一般分类的问题。

    1. 什么是内存或本机位图?
    2. 位图内存与堆内存有何不同?
    4 回复  |  直到 11 年前
        1
  •  33
  •   Trevor Johns    15 年前

    支持位图对象的内存是使用本机代码分配的。( malloc() ),而不是Java new 关键字。这意味着内存由操作系统直接管理,而不是由Dalvik管理。

    本地堆和dalvik堆的唯一真正区别是dalvik的堆是垃圾收集的,而本地堆不是。

    但就这些目的而言,这并没有什么不同。当位图对象被垃圾收集时,它的析构函数将在本机堆中回收相关联的内存。

    来源:

        2
  •  32
  •   hackbod    15 年前

    这里有一个重要的微妙之处:尽管位图像素是在本地堆中分配的,但在Dalvik中的一些特殊技巧却导致它被归类为Java堆。这样做有两个原因:

    (1)为了控制应用程序分配的内存量。如果不进行计算,应用程序可以分配大量内存(因为位图对象本身很小,但可以保留任意大量的本机内存),从而超出16MB或24MB堆限制。

    (2)帮助确定何时进行GC。没有计算,您可以分配和释放对100个位图对象的引用;GC不会运行,因为这些对象很小,但实际上它们可以代表大量实际分配的兆字节,而这些实际分配现在没有及时地进行GCED。通过对Java堆的这些分配进行核算,垃圾回收器将在它认为正在使用的内存中运行。

    请注意,在许多方面,这是一个实现细节;很可能它将来会发生变化,尽管这种基本行为将保持某种形式,因为这两个都是管理位图分配的重要特征。

        3
  •  12
  •   Community CDub    8 年前

    从野外部署中,我发现了以下设备:

    • 限制Java堆16 MIB的设备(位图几乎是无限的)。
    • 限制到16 MIB(Java堆+本地位图存储)的设备
    • 限制Java堆24 MIB的设备(位图几乎是无限的)。
    • 限制到24 MIB(Java堆+本地位图存储)的设备

    24 mib往往是高分辨率设备,可以用runtime.getruntime().maxmemory()检测到。现在也有32mib设备,一些根电话默认有64mib。以前,我有好几次把自己搞糊涂了,想弄清楚到底发生了什么。我认为所有设备都将位图计算到堆限制中。但要对Android机队进行全面的概括是非常困难的。

    这在Android上是一个非常棘手的问题,而且非常令人困惑。这个限制和它的行为记录得很差,很复杂,非常不直观。它们还因设备和操作系统版本而异,并且有几个已知的错误。部分问题是限制不精确-由于堆碎片化,您将在实际限制之前达到OOM,并且必须保守地保留MEG或两个缓冲区。更糟糕的是,我有几个设备,其中有一个本地的Sebug(Android 100%中的一个bug),在你获得Java OOM异常之前就发生了,这使得它永远不能达到极限,因为你甚至不能捕捉到本地崩溃。有关我调查的更多详细信息,请查看 this post . 在同一篇文章中,我解释了如何根据限制来衡量使用情况并避免崩溃。

    Java堆的大小是运行时。GeTrimeMe().ToeTimeMyMy.()。

    无法轻松测量本机位图存储的大小。可以使用debug.getNativeHeapAllocatedSize()测量整个本机堆,但只有位图才算到极限(我认为)。

        4
  •  -1
  •   Mr.Wizard naktepe    11 年前

    我们可以通过使用 android:largeheap="true" 在您的清单文件中。这会解决你的一些问题。