1

My application is running out of memory which switching between two activities. The first activity is running an OpenGL scene, the second activity is not. I want to make sure I am releasing all of the textures used by the OpenGL scene.

Right now I am using this method

getNativeHeapAllocatedSize()

to track the relative amount of memory used by the textures. This number goes up by about 4 megs if I allocate textures. However it never seems to go back down again.

In my first activities 'OnPause' I have the following code:

SurfaceView.onPause();
mTexture = null;

In the second activity I then call getNativeHeapAllocatedSize() several times. Even after the GC has run and the memory still has not dropped.

Edit:

After more research it appears it is something with the code that loads the data. I have removed OpenGL from the equation and the memory is still not being released.

try {
        InputStream is = null;
        {
            AssetManager am = MyActivity.getAssetMgr();
            is = am.open( fileName );
        }

        Bitmap b = BitmapFactory.decodeStream( is );
        if( b != null ) {
            mResX = b.getWidth();
            mResY = b.getHeight();
            Bitmap.Config bc = b.getConfig();
            if( bc == Bitmap.Config.ARGB_8888 )
                mBPP = 4;
            else
                mBPP = 2;

            mImageData = ByteBuffer.allocateDirect( mResX * mResY * mBPP );
            mImageData.order( ByteOrder.nativeOrder() );
            b.copyPixelsToBuffer( mImageData );
            mImageData.position( 0 );


            return true;
        }
    } catch (IOException e) {       
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }       
    return false;
}

Edit2:

I did end up adding in all your ideas. However this seemed to be the problem in my case...

ByteBuffer not releasing memory

Community
  • 1
  • 1
TurqMage
  • 3,321
  • 2
  • 31
  • 52

1 Answers1

3

I am assuming you mean textures loaded to GPU via gl.glTexImage* or any other helper method. In that case GC wont help you, it is not cleaning internal memory used by textures

Have you tried manually deleting your textures via gl.glDeleteTextures?

Edit according to new code:

Several leaks in your code:

  • close the input stream
  • recycle your bitmap after you have copied data to ByteBuffer
  • I guess you use the byteBuffer with image data to upload texture to GPU, make sure you do not store references to those buffers after data was uploaded.

I do not see any other problems in the this code, if after this fixes it still wont work, than look close at any bitmap usages in your app.

Yuriy
  • 817
  • 1
  • 7
  • 17
  • I am just referring to the data being passed to OpenGL. Since I posted earlier I have removed OpenGL from the equation so it must be something with my ByteBuffer or Bitmap handling. On a side note, when using a Surface view would would you call glDeleteTextures? There is function to override when onPause is called, right now I am saying the GL10 object in each texture but it seems a little hacky. – TurqMage Mar 14 '11 at 20:03
  • Regarding glDeleteTextures - in general you should not delete them, android will do it for you. I am just not sure if it will be on app close or activity pause. But anyway memory used in GPU should not affect your second screen – Yuriy Mar 14 '11 at 20:54
  • -close the input stream - Check -recycle your bitmap after you have copied data to ByteBuffer - Check -I guess you use the byteBuffer with image data to upload texture to GPU, make sure you do not store references to those buffers after data was uploaded. - So after I pass the byte buffer in via glTexImage2D, it is fine to release the ByteBuffer? I'll give that a shot. – TurqMage Mar 14 '11 at 22:28