OpenGL ES线程上的垃圾收集

时间:2012-12-17 09:25:04

标签: android opengl-es garbage-collection

我的上一个问题没有答案,所以我尝试了另一种方法。我在运行中将许多纹理(256x256 RGBA888)加载到内存中,并在需要时丢弃它们。问题是有时当我将纹理上传到OpenGL ES时,它需要40-80ms,很少。我发现,这个缓慢的时间是在垃圾收集之后。问题是,这个GC有时会阻塞GL线程(FPS丢弃),有时会阻塞纹理加载器线程(OK)。是否有一种很好的方法可以不允许在GC线程上发生GL

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

是否有某种方法可以删除GC-ing线程上GL以查找在不同线程中解码的位图?我不会在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)

2 个答案:

答案 0 :(得分:2)

您无法完全禁用垃圾收集,它将由Dalvik VM启动而不会入侵。

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

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

答案 1 :(得分:0)

感谢这个video,对于相同大小的磁贴有一个简单的解决方案,并针对Android 3.0及更新版本。

BitmapOptions.inBitmap会为每个新的图块重复使用一个Bitmap,因此不再需要使用一个真实的GC-ing。

相关问题