代码之家  ›  专栏  ›  技术社区  ›  Joshua Weinberg

gldrawElements分配内存而不是释放内存

  •  2
  • Joshua Weinberg  · 技术社区  · 15 年前

    在iPhone3G上使用OpenGles1.1(设备,而不是模拟器),我做的是正常的绘画乐趣。但是在应用程序运行期间的某个时刻,我得到了巨大的内存峰值,在用仪器进行了大量挖掘之后,我发现是gldrawElements在抓取内存。

    正在分配的缓冲区是4Meg,这对我来说意味着它将纹理加载到RAM中,我想这可能是有效的,但它从不释放这个缓冲区,并且正在分配其中的多个。

    如何确保GL创建的这些缓冲区被销毁,而不是仅仅停留在这里?

    3 回复  |  直到 14 年前
        1
  •  2
  •   Andreas Brinck    15 年前

    这听起来不像是一个漏洞,更像是一个驱动程序优化,GPU保存在一个内存块上(VertexBuffer、纹理等),以防再次需要它。如果您运行应用程序一段时间,它是否会一直分配越来越多的内存,直到设备最终耗尽内存?

    不幸的是,第一代iPhone3G没有对顶点缓冲对象(vbo)的适当支持,它们被API公开,但它们的工作方式与普通软件顶点缓冲完全相同。这意味着无论何时你打电话 glDrawElements 无论使用什么顶点缓冲区 glVertexPointer ETC将从系统内存复制到GPU。

    唯一可以将内存“泄漏”到OpenGL的方法是反复分配各种缓冲区对象(纹理对象、顶点缓冲区对象、帧缓冲区对象等),而不释放它们,就像在每个帧中这样:

    GLuint id;  
    glGenTextures(1, &id);
    glBindTexture(GL_TEXTURE_2D, id);        
    glTexImage2D(...);
    

    你最终会失去记忆。我在用 格拉德韦勒斯 在iPhone3G上,我没有看到这个问题,你能给我一个小的repro代码样本吗?

        2
  •  0
  •   Alex Reynolds    15 年前

    检查它是在模拟器上还是在iPhone设备上。仪器/泄漏可以并将在模拟器上报告误报,在设备上不会遇到。

        3
  •  0
  •   Joshua Weinberg    15 年前

    我在IRC的一些人的帮助下解决了这个问题。问题最终是我在应用程序中线程处理的方式。通过将GL和游戏更新循环移动到同一线程,问题就消失了,我不知道为什么另一种方法会导致内存分配,但问题得到了解决。