android - OpenGL ES 线程上的垃圾收集

标签 android opengl-es garbage-collection

我的最后一个问题没有得到解答,所以我正在尝试不同的方法。我将许多纹理 (256x256 RGBA888) 动态加载到内存中,并在需要时丢弃它们。问题是,有时当我将纹理上传到 OpenGL ES 时需要 40-80 毫秒,很少会更多。我发现,这段缓慢的时间是在垃圾收集之后。问题是,此 GC 有时会阻塞 GL 线程(FPS 下降),有时会阻塞纹理加载器线程(正常)。有什么好的方法可以阻止 GCGL 线程上发生吗?

我尝试在每 1、2、3...n 个纹理解码后在纹理加载器线程上调用 System.gc(),这有效地消除了 GC-ingGL 线程上,但现在纹理加载速度慢得多,因为该线程必须等待 GC 完成。使“n”变大会使加载速度更快,但 GL 线程上的 GC 更有可能出现,因此会出现断断续续的动画。

对于在不同线程中解码的位图,是否有一些方法可以删除 GL 线程上的 GC-ing?我不在 GL 线程上解码/分配任何位图,GC-ing 仅在加载新纹理时发生。

编辑: 应用程序针对 android 3.2 及更新版本,也适用于手机。这种情况发生在手机 (HTC One S - 4.0.3) 和平板电脑 (Nexus 7 - 4.1、Galaxy Tab 2 10.1 - 3.2 和 4.0、Acer Icona A200 - 4.0) 上

最佳答案

您无法完全禁用垃圾收集,它将由 Dalvik VM 在您不干预的情况下启动。

您可以通过使用一些自定义纹理加载来最小化内存分配和释放,例如使用预分配数组来存储源纹理数据等。正如您提到的,所有纹理都具有相同的尺寸和颜色深度,因此您需要任何图像的相同大小(256x256x4 = 262144 字节)的临时缓冲区。

最终,您可以将 OpenGL 代码移动到 JNI C/C++ 代码,以您想要的方式管理内存。

关于android - OpenGL ES 线程上的垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13911374/

相关文章:

android - 如何在 Android 的 Mono 中实现 GLSurfaceView.IRenderer?

java - 调整图像大小时内存不足

java - Eclipse 在文件夹中找不到我的项目

java - HttpURLConnection.getOutputStream() 需要 20 秒。为什么?

android - 没有更新电池优化时不渲染 - libgdx

c# - 数组或迭代器 - 对于返回一个/两个元素的调用具有更好的性能特征(内存方面)

java - 获取运行 JVM 的 GC 设置

android - 当应用程序被强行关闭或从最近的应用程序列表中删除时,BroadcastReceiver 不起作用

java - 了解 'getView()'

opengl - glTextureBarrier() 和 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT) 的区别