Osc*_*rEi 4 android opengl-es-2.0
我们有一个应用程序,我们用OpenGL ES 2.0绘制很多东西(主要是OpenStreetMap Tiles,还有其他图像).这工作得很好,但有时应用程序崩溃而没有任何信息 - 这意味着:应用程序只是关闭,而不是消息崩溃,并且logcat中没有消息.
从我们已经发现的实验中可以看出,在将太多纹理加载到OpenGL之后应用程序崩溃了(glGenTextures/glBindTexture)在三星Galaxy S3的实验中,我们能够在RGB888标准中加载多达1800个纹理,大小为256x256.之后,我们的应用程序崩溃,没有任何错误日志.GL_OUT_OF_MEMORY当我们GLES20.glGetError在加载纹理时不断检查OpenGL错误()时,我们不应该收到错误()吗?
一般问:有没有办法确定gpu内存中可用的最大大小,或者至少,我们如何在内存不足时立即收到警告?(问题是我们不知道什么时候我们应该开始删除句柄,我们希望尽可能长时间地保留它们...)
提前感谢您的回复.
Osc*_*rEi 13
经过一些研究,我们找到了解决方案.
但首先: 这些方法不会帮助,要么不会这些.第一篇文章中提到的方法将为你提供绝对无用的数字,它们根本无法帮助你,甚至可能都不正确(因为我的星系S3得到的数字远远高于连接数7.但在我们的测试中,nexus 7可以加载相同数量甚至比S3更多的纹理.
然后让我们继续我们的解决方案 - 我们仍然不确定它是最好的,但它会工作:
它看起来像你可以在OpenGL中保留尽可能多的纹理,因为你有免费的总RAM.是总RAM,而不是堆,而不是与您的应用程序相关的其他东西!这真的是整个系统的可用内存量,没有任何限制!
所以,一旦你弄明白,你只需要读出你拥有的可用内存量:
ActivityManager actvityManager = (ActivityManager) mapView.getActivity().getSystemService( Activity.ACTIVITY_SERVICE );
ActivityManager.MemoryInfo mInfo = new ActivityManager.MemoryInfo ();
actvityManager.getMemoryInfo( mInfo );
Log.v("neom","mema " + mInfo.availMem/1024/1024);
Run Code Online (Sandbox Code Playgroud)
最好的地方可能是你的onSurfaceCreated方法或类似的东西.你在那里获得的内存量是你目前拥有的总可用内存.大多数情况下,这个值太低了,几乎在任何情况下你甚至可以分配比你到那里更多的内存(在我们的测试中,我们可以总是分配比availMem给我们多大约30%-50%的RAM,直到应用程序崩溃(在Nexus上测试) 7(+ 28%),Galaxy S3(+ 36%),变压器T1(+ 57%),Nexus S(+ 57%)).原因是:Android会在内存耗尽之前释放未使用的内容,后台进程等内存.
那么这是什么意思?
您可以(几乎)安全地在OpenGL中保留尽可能多的"纹理字节",因为您有可用的RAM.例如:假设你有375 MB的可用RAM和纹理,每个都有256kb的大小,你可以在开始删除其中一些(使用LRU缓存或类似的东西)之前在OpenGL中保留大约1500个纹理.你甚至可以保持更多,但我认为你这个数量非常安全.
Sureley你也可以availmem更频繁,更适合你的缓存大小或你正在做的新内存 - 但我认为只要你做一次就足够了onSurfaceCreated- 特别是如果你切换它会再次读出到另一个应用程序并返回
| 归档时间: |
|
| 查看次数: |
3841 次 |
| 最近记录: |