我的上一个问题没有答案,所以我尝试了另一种方法。我在运行中将许多纹理(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)
答案 0 :(得分:2)
您无法完全禁用垃圾收集,它将由Dalvik VM启动而不会入侵。
您可以通过使用一些自定义的纹理加载来最小化内存分配和释放,例如使用预先分配的数组来存储源纹理数据等。正如您所提到的,所有纹理都具有相同的尺寸和颜色深度,因此您需要任何图像的相同大小的临时缓冲区(256x256x4 = 262144字节)。
最终,您可以将OpenGL代码移动到JNI C / C ++代码,以便按照您想要的方式管理内存。
答案 1 :(得分:0)
感谢这个video,对于相同大小的磁贴有一个简单的解决方案,并针对Android 3.0及更新版本。
BitmapOptions.inBitmap会为每个新的图块重复使用一个Bitmap
,因此不再需要使用一个真实的GC-ing。