Android 加载大纹理时内存溢出

Android 加载大纹理时内存溢出,android,opengl-es,renderer,glsurfaceview,Android,Opengl Es,Renderer,Glsurfaceview,我有一个GLSurfaceView和一个渲染器,可以在创建的曲面上加载纹理。我的纹理是这样创建的: public Texture3D(final GL10 gl, final int id) { _pBitmap = BitmapFactory.decodeResource(Utils.getResources(), id); gl.glEnable(GL10.GL_TEXTURE_2D); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTIO

我有一个GLSurfaceView和一个渲染器,可以在创建的曲面上加载纹理。我的纹理是这样创建的:

public Texture3D(final GL10 gl, final int id) {
    _pBitmap = BitmapFactory.decodeResource(Utils.getResources(), id);
    gl.glEnable(GL10.GL_TEXTURE_2D);

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
    texture = newTextureID(gl);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
    gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
    gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
    gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);


    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, _pBitmap, 0);

    _pBitmap.recycle();     
    _pBitmap = null;

    gl.glEnable(GL10.GL_BLEND);
}
我将它们存储在HashMap中:

textures.put(R.drawable.tile, new Texture3D(gl, R.drawable.tile));
我的问题是,有时出现以下错误后,从大图像(720x1280,561 Ko)创建纹理时:

04-24 11:05:19.870: D/dalvikvm(27953): GC_CONCURRENT freed 26K, 18% free 50397K/60743K, paused 18ms+6ms, total 57ms
04-24 11:05:19.870: D/dalvikvm(27953): WAIT_FOR_CONCURRENT_GC blocked 2ms
04-24 11:05:19.895: D/dalvikvm(27953): GC_FOR_ALLOC freed 7K, 18% free 50390K/60743K, paused 25ms, total 25ms
04-24 11:05:19.900: I/dalvikvm-heap(27953): Forcing collection of SoftReferences for 14745616-byte allocation
04-24 11:05:19.940: D/dalvikvm(27953): GC_BEFORE_OOM freed 10K, 18% free 50380K/60743K, paused 41ms, total 41ms
04-24 11:05:19.940: E/dalvikvm-heap(27953): Out of memory on a 14745616-byte allocation.
04-24 11:05:19.940: I/dalvikvm(27953): "GLThread 11210" prio=5 tid=35 RUNNABLE
04-24 11:05:19.940: I/dalvikvm(27953):   | group="main" sCount=0 dsCount=0 obj=0x42ec2008 self=0x6095d078
04-24 11:05:19.940: I/dalvikvm(27953):   | sysTid=29199 nice=0 sched=0/0 cgrp=apps handle=1623155456
04-24 11:05:19.940: I/dalvikvm(27953):   | schedstat=( 142147207 17456123 110 ) utm=11 stm=2 core=2
04-24 11:05:19.940: I/dalvikvm(27953):   at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
04-24 11:05:19.945: I/dalvikvm(27953):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:623)
04-24 11:05:19.945: I/dalvikvm(27953):   at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:476)
04-24 11:05:19.945: I/dalvikvm(27953):   at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:499)
04-24 11:05:19.945: I/dalvikvm(27953):   at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:529)
04-24 11:05:19.945: I/dalvikvm(27953):   at com.gbanga.opengl.Texture3D.<init>(Texture3D.java:73)
04-24 11:05:19.945: I/dalvikvm(27953):   at com.gbanga.opengl.Texture3D.setupTextures(Texture3D.java:169)
04-24 11:05:19.945: I/dalvikvm(27953):   at com.gbanga.opengl.OpenGLRenderer.onSurfaceCreated(OpenGLRenderer.java:440)
04-24 11:05:19.950: I/dalvikvm(27953):   at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1494)
04-24 11:05:19.950: I/dalvikvm(27953):   at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
04-24 11:05:19.870:D/dalvikvm(27953):GC_并发释放26K,18%释放50397K/60743K,暂停18ms+6ms,总计57ms
04-24 11:05:19.870:D/dalvikvm(27953):等待并发GC阻塞2ms
4-24 11:05:19.895:D/dalvikvm(27953):释放7K的所有物质的GC_,18%的自由物质50390K/60743K,暂停25ms,总计25ms
04-24 11:05:19.900:I/dalvikvm堆(27953):强制收集14745616字节分配的软引用
04-24 11:05:19.940:D/dalvikvm(27953):释放前的总重量为10K,18%的自由重量为50380K/60743K,暂停时间为41ms,总重量为41ms
04-24 11:05:19.940:E/dalvikvm堆(27953):14745616字节分配的内存不足。
04-24 11:05:19.940:I/dalvikvm(27953):“GLThread 11210”优先级=5 tid=35可运行
04-24 11:05:19.940:I/dalvikvm(27953):| group=“main”scont=0 dsCount=0 obj=0x42ec2008 self=0x6095d078
04-24 11:05:19.940:I/dalvikvm(27953):| sysTid=29199 nice=0 sched=0/0 cgrp=apps handle=1623155456
04-24 11:05:19.940:I/dalvikvm(27953):| schedstat=(142147207 17456123 110)utm=11 stm=2 core=2
04-24 11:05:19.940:I/dalvikvm(27953):在android.graphics.BitmapFactory.NativeDecodeset(本机方法)
04-24 11:05:19.945:I/dalvikvm(27953):在android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:623)
04-24 11:05:19.945:I/dalvikvm(27953):在android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:476)
04-24 11:05:19.945:I/dalvikvm(27953):位于android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:499)
04-24 11:05:19.945:I/dalvikvm(27953):在android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:529)上
04-24 11:05:19.945:I/dalvikvm(27953):位于com.gbanga.opengl.Texture3D。(Texture3D.java:73)
04-24 11:05:19.945:I/dalvikvm(27953):位于com.gbanga.opengl.Texture3D.setupTextures(Texture3D.java:169)
04-24 11:05:19.945:I/dalvikvm(27953):位于com.gbanga.opengl.OpenGLRenderer.onSurfaceCreated(OpenGLRenderer.java:440)
04-24 11:05:19.950:I/dalvikvm(27953):位于android.opengl.GLSurfaceView$GLThread.guarderun(GLSurfaceView.java:1494)
04-24 11:05:19.950:I/dalvikvm(27953):位于android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
这指向构造函数的第一行,在这里我使用
BitmapFactory.decodeResource
。在Galaxy S3上,切换到另一个片段时出现错误,然后返回显示
GLSurfaceView
(在
GLSurfaceView
上调用
onPause
onResume

我怎样才能避免这个问题?我试过了,但我失去了太多的质量和在罕见的情况下发生的错误无论如何(可能在旧的手机型号)


我如何创建/存储纹理是否有问题?你知道为什么我不总是会犯这个错误吗?(通常我在第二次加载纹理时会得到它)。

您可以尝试通过从Android虚拟设备管理器编辑AVD来增加VM堆的大小…

您熟悉:
较新的Androids具有manifest参数:largeHeap=true

如果您的应用程序将处理大量大型纹理,并且如果您希望支持较旧型号的手机,那么在本机端进行opengl处理可能更为有利


NDK中的hello-gl2示例展示了如何实现这一点。在本机端,您将不受应用程序VM强制执行的限制(但是,您应该确保正确管理内存,并且不会导致任何泄漏,因为即使用户关闭您的活动,进程仍将继续运行)

尝试增加VM堆的大小。希望这能帮助你们解决你们的问题…我建议,试着用MAT分析记忆。好的,谢谢你的提示,这可能是我的最后一个选择,因为我需要重新编码所有的东西。谢谢,我会看看这个,但这显然不能适用于所有的设备。我想我需要集中精力减少我的内存使用。