shelll
shelll

Reputation: 3383

Garbage collection on OpenGL ES thread

My last question was unanswered so I am trying a different approach. I load many textures (256x256 RGBA888) into memory on the fly and discard them when needed. Problem is that sometimes when I upload the texture to OpenGL ES it takes 40-80ms, rarely more. I figure out, that this slow time is after a garbage collection. Problem is, that this GC sometimes blocks the GL thread (FPS drop) and sometimes it blocks the texture loader thread (OK). Is there a good way to somehow not allow GC to happen on the GL thread?

I tried calling System.gc() on the texture loader thread after every 1, 2, 3...n textures are decoded and this effectively removed GC-ing on the GL thread, but now the textures load much slower, because that thread must wait for the GC to finish. Making the "n" bigger makes loading faster, but GC on the GL thread is more probable, thus choppy animations.

Is there some way to remove GC-ing on the GL thread for bitmaps decoded in a different thread? I do not decode/allocate any bitmaps on the GL thread and GC-ing happens only when new textures are loaded.

EDIT: App targets android 3.2 and newer, also phones. This happens on phones (HTC One S - 4.0.3) and also tablets (Nexus 7 - 4.1, Galaxy Tab 2 10.1 - 3.2 and 4.0, Acer Icona A200 - 4.0)

Upvotes: 1

Views: 1244

Answers (2)

shelll
shelll

Reputation: 3383

Thanks to this video there is an easy solution for same sized tiles and targeting Android 3.0 and newer.

BitmapOptions.inBitmap which will reuse one Bitmap for every new tile, so no more furios GC-ing.

Upvotes: 0

keaukraine
keaukraine

Reputation: 5364

You cannot completely disable garbage collection, it will be initiated by Dalvik VM without your intrusion.

You can minimize memory allocation and freeing by using some custom loading of textures, like using pre-allocated arrays to store source textures data, etc. As you mentioned, all your textures have the same dimensions and color depth so you will need a temp buffer of the same size (256x256x4 = 262144 bytes) for any image.

Ultimately, you can move OpenGL code to JNI C/C++ code to manage memory the way you want.

Upvotes: 2

Related Questions