0

いくつかの OpenGL/Android チュートリアルから「ViewManager」と呼ぶものをまとめました。問題は、メモリリークが発生していることです。時々 GC 通知を受け取りますが、何もしていないと思います。

11-23 01:50:34.435: D/dalvikvm(954): GC_CONCURRENT freed 381K, 6% free 8024K/8519K, paused 18ms+6ms, total 64ms

私のコードは、GLSurfaceView を拡張し、CallBack と Runnable を実装することから始めます。次に、オブジェクトの更新を処理する gameLoop を作成して開始します。

私のコードからわかるように、リストにはまだオブジェクトがないため、オブジェクトの.drawまたは.updateメソッドでリークは発生していません。

gameLoop を取り出してコードを実行したところ、メモリ リークが停止したように見えました。なぜメモリリークが発生するのかについてのヒントはありますか? ちなみに、run メソッドの呼び出しを削除するThread.sleep(30)と、GC_CONCURRENT 通知を何倍も速く受け取ります。

import java.util.LinkedList;
import java.util.ListIterator;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.view.MotionEvent;


public class ViewManager extends GLSurfaceView implements Runnable, GLSurfaceView.Renderer
{
    private Camera camera;
    private ListIterator<GameObject> objIterator;
    private LinkedList<GameObject> objects;
    private Thread gameThread;
    private boolean running;

    public ViewManager(Context context)
    {
        super(context);
        setRenderer(this);

        objects = new LinkedList<GameObject>();

        camera = new Camera();
        camera.setPosZ(-4.0f);

    }

    public void onDrawFrame(GL10 gl)
    {
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT|GL10.GL_COLOR_BUFFER_BIT);

        //3D Drawing
        objIterator = objects.listIterator();
        gl.glLoadIdentity();
        camera.draw(gl);    
        while(objIterator.hasNext())
        {
            gl.glPushMatrix();
            objIterator.next().draw(gl);
            gl.glPopMatrix();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        if(event.getAction() == MotionEvent.ACTION_DOWN)
        {
            camera.getPreviouslyTouchedPoint().set((int)event.getX(),(int)event.getY());
        }

        if(event.getAction() == MotionEvent.ACTION_MOVE)
        {
            camera.setPosX(camera.getPosX() - (camera.getPreviouslyTouchedPoint().x-event.getX())/100f);
            camera.setPosY(camera.getPosY() - (camera.getPreviouslyTouchedPoint().y-event.getY())/100f);
        }

        camera.getPreviouslyTouchedPoint().set((int)event.getX(),(int)event.getY());

        return true;
    }
    public void onSurfaceChanged(GL10 gl, int width, int height)
    {
        running = false;

        gl.glViewport(0,0,width,height);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        GLU.gluPerspective(gl, 45.0f, (float)width/(float)height,0.1f,100.0f);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();

        running = true;
        gameThread = new Thread(this);
        gameThread.start();
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig arg1)
    {
        gl.glShadeModel(GL10.GL_SMOOTH);
        gl.glClearDepthf(1.0f);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
    }

    public void run()
    {
        ListIterator<GameObject> itr = objects.listIterator();

        while(running)
        {
            itr = objects.listIterator();
            while(itr.hasNext())
            {
                itr.next().update(0);
            }
            try
            {
                Thread.sleep(30);
            } catch (InterruptedException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}
4

1 に答える 1

0

メモリ リークと実行中の GC の間には、常に混乱があります (ただし、これらはほぼ正反対の状況です)。GC がこれらのオブジェクトを収集するのを妨げているオブジェクトへの参照がある場合、メモリ リークが発生します。GC は、アクティブなスレッド (オブジェクトの場合) によって参照されなくなったオブジェクトを収集しますListIterator

スレッドが終了すると、スレッドListIteratorはアクティブなスレッドから参照されなくなるため、GC はスレッドを収集します。

GC が実行されないようにするには、スレッドが終了する前に自分で参照を削除します (run()メソッド内)。メソッドの最後でこのオブジェクトを無効にするrun()か、毎回再利用するクラス レベルIteratorオブジェクトを使用します (スレッドが終了するたびに新しいオブジェクトを作成しない実行されます)。

于 2012-11-25T00:16:52.010 に答える