Android 异常OutofMemoryError dalvik.system.VMRuntime.newNonMovableArray(本机方法)
我正在使用OpenGl Es库渲染3D对象。我试图在谷歌上搜索,但没能成功,这是一个例外 请帮我解决这个问题Android 异常OutofMemoryError dalvik.system.VMRuntime.newNonMovableArray(本机方法),android,opengl-es,Android,Opengl Es,我正在使用OpenGl Es库渲染3D对象。我试图在谷歌上搜索,但没能成功,这是一个例外 请帮我解决这个问题 package com.amplimesh.models; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.ByteBuffer; import java.nio
package com.amplimesh.models;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
import android.util.Log;
import com.amplimesh.util.Point3;
public class ObjModel {
public void bindTextures(Context context, GL10 gl) {
Bitmap bitmap;
try {
InputStream is = context.getAssets().open("textures/"+mTextureName);
bitmap = BitmapFactory.decodeStream(is);
if (bitmap == null) {
Log.v("ObjModel", "err loading bitmap!");
}
} catch (java.io.IOException e) {
Log.v("ObjModel", "err loading tex: "+e.toString());
return;
}
mTextures = new int[1];
gl.glGenTextures(1, mTextures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextures[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
public void draw(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
for (Model model : mModels) {
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, model.v);
if (model.vt != null && mTextures != null) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextures[0]);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, model.vt);
}
if (model.vn != null) {
gl.glNormalPointer(GL10.GL_FLOAT, 0, model.vn);
}
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, model.v_size);
}
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
public static ObjModel loadFromStream(InputStream is, String texture_name) throws IOException {
ObjModel obj = ObjLoader.loadFromStream(is);
obj.mTextureName = texture_name;
return obj;
}
private Model mModels[];
private int mTextures[];
private String mTextureName;
/**
* It help to load the obj.
* @author Ajay
*/
private static class ObjLoader {
public static ObjModel loadFromStream(InputStream is) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
ObjModel obj = new ObjModel();
ArrayList<Point3> v = new ArrayList<Point3>();
ArrayList<Point3> vt = new ArrayList<Point3>();
ArrayList<Point3> vn = new ArrayList<Point3>();
ArrayList<Face> f = new ArrayList<Face>();
ArrayList<Model> o = new ArrayList<Model>();
boolean o_pending=false;
while(reader.ready()) {
String line = reader.readLine();
if (line == null)
break;
StringTokenizer tok = new StringTokenizer(line);
String cmd = tok.nextToken();
if (cmd.equals("o")) {
if (o_pending) {
Model model = new Model();
model.fill(f, vt.size() > 0, vn.size() > 0);
o.add(model);
}
else {
o_pending=true;
}
}
else
if (cmd.equals("v")) {
v.add(read_point(tok));
}
else
if (cmd.equals("vn")) {
vn.add(read_point(tok));
}
else
if (cmd.equals("vt")) {
vt.add(read_point(tok));
}
else
if (cmd.equals("f")) {
if (tok.countTokens() != 3)
continue;
Face face = new Face(3);
while (tok.hasMoreTokens()) {
StringTokenizer face_tok = new StringTokenizer(tok.nextToken(), "/");
int v_idx = -1;
int vt_idx = -1;
int vn_idx = -1;
v_idx = Integer.parseInt(face_tok.nextToken());
if (face_tok.hasMoreTokens()) vt_idx = Integer.parseInt(face_tok.nextToken());
if (face_tok.hasMoreTokens()) vn_idx = Integer.parseInt(face_tok.nextToken());
//Log.v("objmodel", "face: "+v_idx+"/"+vt_idx+"/"+vn_idx);
face.addVertex(
v.get(v_idx-1),
vt_idx == -1 ? null : vt.get(vt_idx-1),
vn_idx == -1 ? null : vn.get(vn_idx-1)
);
}
f.add(face);
}
}
if (o_pending) {
Model model = new Model();
model.fill(f, vt.size() > 0, vn.size() > 0);
o.add(model);
}
obj.mModels = new Model[o.size()];
o.toArray(obj.mModels);
return obj;
}
private static Point3 read_point(StringTokenizer tok) {
Point3 ret = new Point3();
if (tok.hasMoreTokens()) {
ret.x = Float.parseFloat(tok.nextToken());
if (tok.hasMoreTokens()) {
ret.y = Float.parseFloat(tok.nextToken());
if (tok.hasMoreTokens()) {
ret.z = Float.parseFloat(tok.nextToken());
}
}
}
return ret;
}
}
private static class Face {
Point3 v[];
Point3 vt[];
Point3 vn[];
int size;
int count;
public Face(int size) {
this.size = size;
this.count = 0;
this.v = new Point3[size];
this.vt = new Point3[size];
this.vn = new Point3[size];
}
public boolean addVertex(Point3 v, Point3 vt, Point3 vn) {
if (count >= size)
return false;
this.v[count] = v;
this.vt[count] = vt;
this.vn[count] = vn;
count++;
return true;
}
public void pushOnto(FloatBuffer v_buffer, FloatBuffer vt_buffer, FloatBuffer vn_buffer) {
int i;
for (i=0; i<size; i++) {
v_buffer.put(v[i].x); v_buffer.put(v[i].y); v_buffer.put(v[i].z);
if (vt_buffer != null && vt[i] != null) {
vt_buffer.put(vt[i].x); vt_buffer.put(vt[i].y);
}
if (vn_buffer != null && vn[i] != null) {
vn_buffer.put(vn[i].x); vn_buffer.put(vn[i].y); vn_buffer.put(vn[i].z);
}
}
}
}
private static class Model {
public FloatBuffer v;
public FloatBuffer vt;
public FloatBuffer vn;
public int v_size;
public void fill(ArrayList<Face> faces, boolean has_tex, boolean has_normals) {
int f_len = faces.size();
this.v_size = f_len * 3;
ByteBuffer tBuf = ByteBuffer.allocateDirect(this.v_size*3 * 4);
tBuf.order(ByteOrder.nativeOrder());
this.v = tBuf.asFloatBuffer();
if (has_tex) {
ByteBuffer vtBuf = ByteBuffer.allocateDirect(this.v_size*3 * 4);
vtBuf.order(ByteOrder.nativeOrder());
this.vt = vtBuf.asFloatBuffer();
}
if (has_normals) {
ByteBuffer vnBuf = ByteBuffer.allocateDirect(this.v_size*3 * 4);
vnBuf.order(ByteOrder.nativeOrder());
this.vn = vnBuf.asFloatBuffer();
}
int i;
for (i=0; i < f_len; i++) {
Face face = faces.get(i);
face.pushOnto(this.v, this.vt, this.vn);
}
this.v.rewind();
if (this.vt != null)
this.vt.rewind();
if (this.vn != null)
this.vn.rewind();
}
}
}
package com.amplimesh.models;
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.nio.ByteBuffer;
导入java.nio.ByteOrder;
导入java.nio.FloatBuffer;
导入java.util.ArrayList;
导入java.util.StringTokenizer;
导入javax.microedition.khronos.opengles.GL10;
导入android.content.Context;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.opengl.GLUtils;
导入android.util.Log;
导入com.amplimesh.util.Point3;
公共类对象模型{
公共void绑定纹理(上下文,GL10 gl){
位图;
试一试{
InputStream=context.getAssets().open(“纹理/”+mTextureName);
位图=BitmapFactory.decodeStream(is);
如果(位图==null){
v(“ObjModel”,“加载位图出错!”);
}
}捕获(java.io.ioe异常){
Log.v(“ObjModel”,“errloadingtex:+e.toString());
返回;
}
mTextures=newint[1];
gl.glGenTextures(1,mTextures,0);
gl.glBindTexture(GL10.gl_TEXTURE_2D,mTextures[0]);
gl.glTexParameterf(GL10.gl\u纹理\u 2D,GL10.gl\u纹理\u最小\u过滤器,GL10.gl\u线性);
gl.glTexParameterf(GL10.gl\u纹理\u 2D,GL10.gl\u纹理\u MAG\u过滤器,GL10.gl\u线性);
gl.glTexParameterf(GL10.gl\u纹理\u 2D、GL10.gl\u纹理\u包裹、GL10.gl\u夹紧到边缘);
gl.glTexParameterf(GL10.gl\u纹理\u 2D、GL10.gl\u纹理\u包裹、GL10.gl\u夹紧到边缘);
GLUtils.texImage2D(GL10.GL_纹理_2D,0,位图,0);
bitmap.recycle();
}
公共作废提款(GL10 gl){
gl.glEnableClientState(GL10.gl_顶点数组);
gl.glEnableClientState(GL10.gl_纹理_坐标_数组);
gl.glEnableClientState(GL10.gl\u NORMAL\u数组);
用于(模型:mModels){
gl.glVertexPointer(3,GL10.gl_FLOAT,0,model.v);
if(model.vt!=null&&mTextures!=null){
gl.glBindTexture(GL10.gl_TEXTURE_2D,mTextures[0]);
gl.glTexCoordPointer(2,GL10.gl_FLOAT,0,model.vt);
}
如果(model.vn!=null){
gl.glNormalPointer(GL10.gl_FLOAT,0,model.vn);
}
gl.gldrawArray(GL10.gl_三角形,0,model.v_大小);
}
gl.glDisableClientState(GL10.gl\u NORMAL\u数组);
gl.glDisableClientState(GL10.gl_顶点数组);
gl.glDisableClientState(GL10.gl_纹理_坐标_数组);
}
公共静态ObjModel loadFromStream(InputStream为,字符串纹理_名称)引发IOException{
ObjModel obj=ObjLoader.loadFromStream(is);
obj.mTextureName=纹理名称;
返回obj;
}
私有模型MMODEL[];
私有内部文本[];
私有字符串mTextureName;
/**
*它有助于加载obj。
*@作者阿杰
*/
私有静态类ObjLoader{
公共静态ObjModel loadFromStream(InputStream为)引发IOException{
BufferedReader reader=新的BufferedReader(新的InputStreamReader(is));
ObjModel obj=新的ObjModel();
ArrayList v=新的ArrayList();
ArrayList vt=新的ArrayList();
ArrayList vn=新的ArrayList();
ArrayList f=新的ArrayList();
ArrayList o=新的ArrayList();
布尔o_pending=false;
while(reader.ready()){
字符串行=reader.readLine();
如果(行==null)
打破
StringTokenizer tok=新的StringTokenizer(行);
字符串cmd=tok.nextToken();
if(cmd.equals(“o”)){
如果(o_待定){
模型=新模型();
模型填充(f,vt.size()>0,vn.size()>0);
o、 添加(模型);
}
否则{
o_pending=true;
}
}
其他的
如果(cmd.equals(“v”)){
v、 添加(读取点(tok));
}
其他的
如果(cmd.equals(“vn”)){
vn.添加(读取点(tok));
}
其他的
如果(指令等于(“vt”)){
vt.add(读取点(tok));
}
其他的
如果(cmd.equals(“f”)){
if(tok.countTokens()!=3)
继续;
面=新面(3);
while(tok.hasMoreTokens()){
StringTokenizer face_tok=新的StringTokenizer(tok.nextToken(),“/”;
int v_idx=-1;
int vt_idx=-1;
int vn_idx=-1;
v_idx=Integer.parseInt(face_tok.nextToken());
if(face_tok.hasMoreTokens())vt_idx=Integer.parseInt(face_tok.nextToken());
if(face_tok.hasMoreTokens())vn_idx=Integer.parseInt(face_tok.nextToken());
//Log.v(“objmodel”,“face:+v_idx+”/“+vt_idx+”/“+vn_idx”);
face.addVertex(
v、 get(v_idx-1),
vt_idx==-1?null:vt.get(vt_i
08-03 16:22:31.794: E/AndroidRuntime(18878): FATAL EXCEPTION: AsyncTask #3
08-03 16:22:31.794: E/AndroidRuntime(18878): java.lang.RuntimeException: An error occured while executing doInBackground()
08-03 16:22:31.794: E/AndroidRuntime(18878): at android.os.AsyncTask$3.done(AsyncTask.java:278)
08-03 16:22:31.794: E/AndroidRuntime(18878): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
08-03 16:22:31.794: E/AndroidRuntime(18878): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
08-03 16:22:31.794: E/AndroidRuntime(18878): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
08-03 16:22:31.794: E/AndroidRuntime(18878): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-03 16:22:31.794: E/AndroidRuntime(18878): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
08-03 16:22:31.794: E/AndroidRuntime(18878): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
08-03 16:22:31.794: E/AndroidRuntime(18878): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
08-03 16:22:31.794: E/AndroidRuntime(18878): at java.lang.Thread.run(Thread.java:856)
08-03 16:22:31.794: E/AndroidRuntime(18878): Caused by: java.lang.OutOfMemoryError
08-03 16:22:31.794: E/AndroidRuntime(18878): at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
08-03 16:22:31.794: E/AndroidRuntime(18878): at java.nio.MemoryBlock.allocate(MemoryBlock.java:126)
08-03 16:22:31.794: E/AndroidRuntime(18878): at java.nio.ReadWriteDirectByteBuffer.<init>(ReadWriteDirectByteBuffer.java:46)
08-03 16:22:31.794: E/AndroidRuntime(18878): at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:68)
08-03 16:22:31.794: E/AndroidRuntime(18878): at com.amplimesh.models.ObjModel$Model.fill(ObjModel.java:241)
08-03 16:22:31.794: E/AndroidRuntime(18878): at com.amplimesh.models.ObjModel$ObjLoader.loadFromStream(ObjModel.java:161)
08-03 16:22:31.794: E/AndroidRuntime(18878): at com.amplimesh.models.ObjModel.loadFromStream(ObjModel.java:74)
08-03 16:22:31.794: E/AndroidRuntime(18878): at com.amplimesh.renderer.RendererView$ObjLoaderAsync.doInBackground(RendererView.java:443)
08-03 16:22:31.794: E/AndroidRuntime(18878): at com.amplimesh.renderer.RendererView$ObjLoaderAsync.doInBackground(RendererView.java:1)
08-03 16:22:31.794: E/AndroidRuntime(18878): at android.os.AsyncTask$2.call(AsyncTask.java:264)
08-03 16:22:31.794: E/AndroidRuntime(18878): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-03 16:22:31.794: E/AndroidRuntime(18878): ... 5 more
<application android:largeHeap="true"