Android opengles纹理存储器

Android opengles纹理存储器,android,opengl-es,Android,Opengl Es,我试图在我的原生Android应用程序中优化纹理内存消耗。我有两个计数器:第一个是我自己的计数器,每次调用TexImage时都会递增: g_cbTextureMemory += ImageLineBytes(Format, width) * height; 您可以假设TexImage为纹理调用了一次,在我的真实代码中,如果纹理重新分配,但实际上没有重新分配,则当前图像的大小比添加新图像的大小要小 二是从制度上, adb shell dumpsys meminfo my.app.name 它给

我试图在我的原生Android应用程序中优化纹理内存消耗。我有两个计数器:第一个是我自己的计数器,每次调用TexImage时都会递增:

g_cbTextureMemory += ImageLineBytes(Format, width) * height;
您可以假设TexImage为纹理调用了一次,在我的真实代码中,如果纹理重新分配,但实际上没有重新分配,则当前图像的大小比添加新图像的大小要小

二是从制度上,

adb shell dumpsys meminfo my.app.name
它给出了如下内容:

    ** MEMINFO in pid 3269 [my.app.name] **
                    native   dalvik    other    total
            size:    39320[*]  6663      N/A    45983
       allocated:    21453     3945      N/A    25398
            free:       34     2718      N/A     2752
           (Pss):     6281     3078    40643    50002
  (shared dirty):     2240     4968    12108    19316
    (priv dirty):     6232     2684    17948    26864
之后,我执行以下操作:我将所有纹理替换为1x1(通过将虚拟1x1图像发送到glTexImage)。我看到meminfo给出了另一个结果,22Mb上的差异单元格[*]发生了变化。但是我的计数器显示我有25Mb的纹理,所以我希望是25Mb

那么转储纹理内存消耗隐藏在哪里呢?需要明确的是,1x1纹理转储为:

    ** MEMINFO in pid 3269 [my.app.name] **
                    native   dalvik    other    total
            size:    16892     5575      N/A    22467
       allocated:    13211     3574      N/A    16785
            free:      208     2001      N/A     2209
           (Pss):     6273     3122    17016    26411
  (shared dirty):     2252     5032    10756    18040
   (priv dirty):      6224     2588     5848    14660

为什么我没有得到25Mb?是统计误差吗?本机堆是否包含纹理内存(似乎是)?或者对于某些格式,Android的内部格式与我发送的不同?例如,R8G8B8被转化为更优化的产品(似乎不是)?也许一切都好,还有合理的解释吗?

这里有几个问题

我假设您通过比较“大小”行得到22MB的差异。这是进程请求的总内存量。有两个因素可以促成该值

首先,该区域中的许多虚拟页可能(也可能)没有分配给物理内存。只有当进程实际引用以前未使用的虚拟页时,才会发生物理分配。在这种情况下,MMU会使CPU陷入内核,然后内核会找到并分配一个物理页以支持虚拟页。因此,一个进程的大小可能远远超过可用的物理RAM,即使在没有交换空间的便携式Android设备上,只要这些页面中的大多数从未被引用过

影响进程大小的第二个因素是C库(或Dalvik VM,或任何用户空间内存管理)将请求比应用程序请求的内存块更大的内存块。这样做是出于性能原因,因为可以在不进行系统调用的情况下频繁分配/取消分配小缓冲区。因此,上面的size参数不能很好地指示进程使用的实际内存-它只能作为粗略的上限。事实上,“分配”行可以更好地指示应用程序使用的最大内存,因为它跟踪实际引用的页面

无论如何,据我所知,通过glTexImage发送到OpenGL的任何纹理都会复制到单独的内存区域。这可能在图形硬件本身上,也可能作为内核空间中内核视频驱动程序的一部分。无论哪种方式,所使用的纹理内存都不会反映在应用程序中

希望有帮助