[英]My application crashes because according to the garbage collector, only 4% heap memory is remaining… How do I prevent this?
我在Android應用程序中使用位圖,並打開GLES 2.0渲染它們。 該應用程序崩潰,釋放的日志GC_FOR_ALLOC <1K,免費的4%12240K / 12640K。我的目標是從手機/平板電腦的gallery文件夾中渲染位圖。 一切正常。 我收集所有紋理(圖像)詳細信息(必須在屏幕上進行渲染的位置以及紋理的圖像名稱= MyApplication.getTextures();紋理是一個不斷增長的數組列表。因此,在我的onDrawFrame中,我在繪制每一幀中的所有紋理。請注意,位圖來自圖庫而不是資源文件夾。這是代碼:
package com.example.hmi_abp;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;`
import java.nio.ShortBuffer;
import java.util.ArrayList;
import javax.microedition.khronos.egl.EGLConfig;`
import javax.microedition.khronos.opengles.GL10;
import com.example.rendering.TextureHelper;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.opengl.Matrix;
public class GLRenderer implements Renderer {
// Our matrices
private final float[] mtrxProjection = new float[16];
private final float[] mtrxView = new float[16];
private final float[] mtrxProjectionAndView = new float[16];
// Geometric variables
public static float vertices[][];
public static short indices[][];
public FloatBuffer vertexBuffer[];
public ShortBuffer drawListBuffer[];
public static float uvs[][];
public FloatBuffer uvBuffer[];
private final Context mActivityContext;
// Our screenresolution
float mScreenWidth = 1280;
float mScreenHeight = 768;
// Misc
Context mContext;
int mProgram;
int number;
private ArrayList<TextureProperties> textures;
private int[] mTextureDataHandle;
public GLRenderer(Context c)
{
mActivityContext = c;
}
public void onPause()
{
/* Do stuff to pause the renderer */
}
public void onResume()
{
}
@Override
public synchronized void onDrawFrame(GL10 unused) {
textures=MyApplication.getTextures();
number = textures.size();
System.out.println("number"+ number);
mTextureDataHandle = new int[number];
vertices=new float[number][12];
uvs=new float[number][8];
indices=new short [number][6];
vertexBuffer = new FloatBuffer[number];
drawListBuffer= new ShortBuffer[number];
uvBuffer=new FloatBuffer[number];
int k=0,h,w;
for(;k<number;k++)
{
Bitmap bitmap =BitmapFactory.decodeFile(textures.get(k).name);
h=bitmap.getHeight();
w=bitmap.getWidth();
setUpBuffers(k,h,w);
Render(mtrxProjectionAndView,k);
}
}
private synchronized void Render(float[] m, int k) {
mTextureDataHandle[k] =
TextureHelper.loadTexture(mActivityContext,textures.get(k).name);
// get handle to vertex shader's vPosition member
int mPositionHandle=GLES20.glGetAttribLocation(riGraphicTools.sp_Image,"vPosition");
// Enable generic vertex attribute array
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, 3,
GLES20.GL_FLOAT, false,
0, vertexBuffer[k]);
// Get handle to texture coordinates location
int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "a_texCoord" );
// Enable generic vertex attribute array
GLES20.glEnableVertexAttribArray ( mTexCoordLoc );
// Prepare the texturecoordinates
GLES20.glVertexAttribPointer ( mTexCoordLoc, 2, GLES20.GL_FLOAT,
false,
0, uvBuffer[k]);
// Get handle to shape's transformation matrix
int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "uMVPMatrix");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, mtrxProjectionAndView, 0);
// Get handle to textures locations
int mSamplerLoc = GLES20.glGetUniformLocation (riGraphicTools.sp_Image, "s_texture" );
// Set the sampler texture unit to 0, where we have saved the texture.
GLES20.glUniform1i ( mSamplerLoc, 0);
// System.out.println(k);
// Draw the triangle
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices[k].length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer[k]);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTexCoordLoc);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// We need to know the current width and height.
mScreenWidth = width;
mScreenHeight = height;
// Redo the Viewport, making it fullscreen.
GLES20.glViewport(0, 0, (int)mScreenWidth, (int)mScreenHeight);
// Clear our matrices
for(int i=0;i<16;i++)
{
mtrxProjection[i] = 0.0f;
mtrxView[i] = 0.0f;
mtrxProjectionAndView[i] = 0.0f;
}
// Setup our screen width and height for normal sprite translation.
Matrix.orthoM(mtrxProjection, 0, 0f, mScreenWidth, 0.0f, mScreenHeight, 0, 50);
// Set the camera position (View matrix)
Matrix.setLookAtM(mtrxView, 0, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// Calculate the projection and view transformation
Matrix.multiplyMM(mtrxProjectionAndView, 0, mtrxProjection, 0, mtrxView, 0);
}
@Override
public synchronized void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Set the clear color to black
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1);
// Create the shaders, solid color
int vertexShader = riGraphicTools.loadShader(GLES20.GL_VERTEX_SHADER, riGraphicTools.vs_SolidColor);
int fragmentShader = riGraphicTools.loadShader(GLES20.GL_FRAGMENT_SHADER, riGraphicTools.fs_SolidColor);
riGraphicTools.sp_SolidColor = GLES20.glCreateProgram(); // create empty OpenGL ES Program
GLES20.glAttachShader(riGraphicTools.sp_SolidColor, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(riGraphicTools.sp_SolidColor, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(riGraphicTools.sp_SolidColor); // creates OpenGL ES program executables
// Create the shaders, images
vertexShader = riGraphicTools.loadShader(GLES20.GL_VERTEX_SHADER, riGraphicTools.vs_Image);
fragmentShader = riGraphicTools.loadShader(GLES20.GL_FRAGMENT_SHADER, riGraphicTools.fs_Image);
riGraphicTools.sp_Image = GLES20.glCreateProgram(); // create empty OpenGL ES Program
GLES20.glAttachShader(riGraphicTools.sp_Image, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(riGraphicTools.sp_Image, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(riGraphicTools.sp_Image); // creates OpenGL ES program executables
// Set our shader programm
GLES20.glUseProgram(riGraphicTools.sp_Image);
}
public synchronized void setUpBuffers(int k, int h, int w)
{
// We have to create the vertices of our triangle.
vertices[k] = new float[number*12];
vertices[k][0]= textures.get(k).xPos;
vertices[k][1]= textures.get(k).yPos;
vertices[k][2]= 0.0f;
vertices[k][3]= textures.get(k).xPos;
vertices[k][4]= textures.get(k).yPos-h;
vertices[k][5]= 0.0f;
vertices[k][6]= textures.get(k).xPos+w;
vertices[k][7]= textures.get(k).yPos-h;
vertices[k][8]= 0.0f;
vertices[k][9]= textures.get(k).xPos+w;
vertices[k][10]= textures.get(k).yPos;
vertices[k][11]= 0.0f;
// The vertex buffer.
ByteBuffer bb = ByteBuffer.allocateDirect(vertices[k].length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer[k] = bb.asFloatBuffer();
vertexBuffer[k].put(vertices[k]);
vertexBuffer[k].position(0);
indices[k] = new short[number*6];
indices[k][0] = 0;//(short) (k*4);
indices[k][1] = 1;//(short) (k*4+1);
indices[k][2] = 2;//(short) (k*4+2);
indices[k][3] = 0;//(short) (k*4);
indices[k][4] = 2;//(short) (k*4+2);
indices[k][5] = 3;//(short) (k*4+3);
// initialize byte buffer for the draw list
ByteBuffer dlb = ByteBuffer.allocateDirect(indices[k].length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer[k] = dlb.asShortBuffer();
drawListBuffer[k].put(indices[k]);
drawListBuffer[k].position(0);
// Create our UV coordinates.
uvs[k] = new float[number*8];
uvs[k][0]=0.0f;
uvs[k][1]=0.0f;
uvs[k][2]=0.0f;
uvs[k][3]=1.0f;
uvs[k][4]=1.0f;
uvs[k][5]=1.0f;
uvs[k][6]=1.0f;
uvs[k][7]=0.0f;
// The texture buffer
ByteBuffer bb2 = ByteBuffer.allocateDirect(uvs[k].length * 4);
bb2.order(ByteOrder.nativeOrder());
uvBuffer[k] = bb2.asFloatBuffer();
uvBuffer[k].put(uvs[k]);
uvBuffer[k].position(0);
}
}
您應該在清單文件中使用android:largeHeap="true"
來請求更大的堆大小,但這不適用於任何之前的Honeycomb設備。 在2.3版之前的設備上,您可以使用VMRuntime類,但是在Gingerbread及更高版本上將無法使用。
具有最大限制的唯一方法是通過NDK執行內存密集型任務,因為NDK不會像SDK那樣施加內存限制。
或者,您可以使用以下方法:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.