簡體   English   中英

在Android設備上的OpenGL中進行適當的內存管理

[英]Proper memory management in OpenGL on Android devices

我們有一個應用程序,我們用OpenGL ES 2.0繪制很多東西(主要是OpenStreetMap Tiles,還有其他圖像)。 這工作得很好,但有時應用程序崩潰而沒有任何信息 - 這意味着:應用程序只是關閉,而不是消息崩潰,並且logcat中沒有消息。

從我們已經發現的實驗中看出,在將太多紋理加載到OpenGL之后應用程序崩潰了( glGenTextures/glBindTexture )在三星glGenTextures/glBindTexture S3的實驗中,我們能夠在RGB888標准中加載多達1800個紋理,大小為256x256。 之后,我們的應用程序崩潰,沒有任何錯誤日志。 當我們在加載紋理時不斷檢查OpenGL錯誤( GLES20.glGetError )時,我們不應該收到錯誤( GL_OUT_OF_MEMORY )嗎?

一般問:有沒有辦法確定gpu內存中可用的最大大小,或者至少,我們如何在內存不足時立即收到警告? (問題是我們不知道什么時候應該開始刪除句柄,我們希望盡可能長時間地保留它們...)

提前感謝您的回復。

經過一些研究,我們找到了解決方案。

但首先: 這些方法不會幫助,要么不會這些 第一篇文章中提到的方法將為你提供絕對無用的數字,這些數字根本無法幫助你,甚至可能都不正確(因為我的星系S3得到的數字遠遠高於nexus 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);

最好的地方可能在你的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做一次就足夠了 - 特別是因為這將再次讀出來你切換到另一個應用程序並返回。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM