OpenGL内存泄漏问题分析一:glGenTextures引发的内存泄漏
使用OpenGL渲染本地图片的时候频繁调用glGenTextures()用于产出textureId,代码如下:
public int createTextureObjectFromBitmap(int defaultId, Bitmap bitmap) {
//之前没有复用textureId,会导致内存泄漏
if (defaultId == 0) {
final int[] textureObjectIds = new int[1];
GLES20.glGenTextures(1, textureObjectIds, 0);【 内存OOM 点,重复创建纹理】
textureId = textureObjectIds[0];
}
if (textureId == 0) {
Log.e(TAG, "Could not generate a new OpenGL texture object!");
return 0;
}
if (bitmap != null && !bitmap.isRecycled()) {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
//根据以上指定的参数,生成一个2D纹理
//第一个参数指定了纹理目标(Target)。设置为GL_TEXTURE_2D意味着会生成与当前绑定的纹理对象在同一个目标上的纹理(任何绑定到GL_TEXTURE_1D和GL_TEXTURE_3D的纹理不会受到影响)。
//第二个参数为纹理指定多级渐远纹理的级别,如果你希望单独手动设置每个多级渐远纹理的级别的话。这里我们填0,也就是基本级别。
//第三个参数告诉OpenGL我们希望把纹理储存为何种格式。我们的图像只有RGB值,因此我们也把纹理储存为RGB值。
//第四个和第五个参数设置最终的纹理的宽度和高度。我们之前加载图像的时候储存了它们,所以我们使用对应的变量。
//下个参数应该总是被设为0(历史遗留问题)。
//第七第八个参数定义了源图的格式和数据类型。我们使用RGB值加载这个图像,并把它们储存为char(byte)数组,我们将会传入对应值。
//最后一个参数是真正的图像数据。
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
return textureId;
}
return 0;
}