1

現在、Android GLSurfaceView() で次の openGL 呼び出し onDrawFrame() を作成しています。

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, cameraTexture[0]);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, camPreviewSize.width, camPreviewSize.height, 0, GLES20.GL_LUMINANCE,     GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(yArray));
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);

setPreviewCallback()カメラ内のAndroidの機能を使用してカスタムコールバックメソッドを使用してAndroidカメラプレビューからのライブフィードを処理しているため、フレームごとにこれ(またはそれに似たもの)を実行する必要がありますが、ガベージコレクションは完全にワイルドになります(次の繰り返しについて毎秒 10 倍!):

....

GC_FOR_ALLOC freed 1530K, 42% free 3671K/6307K, paused 18ms
GC_FOR_ALLOC freed 1530K, 42% free 3671K/6307K, paused 22ms
GC_FOR_ALLOC freed 1530K, 42% free 3671K/6307K, paused 25ms
GC_FOR_ALLOC freed 1530K, 42% free 3671K/6307K, paused 20ms
GC_FOR_ALLOC freed 1530K, 42% free 3671K/6307K, paused 20ms
GC_FOR_ALLOC freed 1530K, 42% free 3671K/6307K, paused 16ms
GC_FOR_ALLOC freed 1530K, 42% free 3671K/6307K, paused 22ms

....

yArrayはバイト配列であり、バッファにラップします。私はDDMSを使用してプロファイリングを行いましたが、実際、割り当ての大部分はバイト配列であり、ラップ関数で行った読み取りから、ラップの呼び出しで基になるバイト[]を作成する可能性があるようです。テクスチャとして使用された後、GC によって収集されます。

割り当て数を減らすにはどうすればよいですか? どうにかして GL 呼び出しで変更する必要がありますか? 代わりに同じバイト配列を再利用できるようですが、方法がわかりません。

どんな助けでも大歓迎です!この量のゴミは私を怖がらせます!

4

2 に答える 2

4

過剰なガベージ コレクションを引き起こすメソッドに関連する、十分に文書化された Android バグがあります。setPreviewCallback()この問題の解決策は、メソッドを使用しsetPreviewCallbackWithBufferてすべてのフレームに追加および再追加されるバッファーを事前に割り当てる新しい方法を使用することですaddCallbackBuffer

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
...
  mCamera.addCallbackBuffer(callbackBuffer);
  mCamera.setPreviewCallbackWithBuffer(class that implements PreviewCallback);
...
}

onPreviewFrame 関数では、バッファを再度追加する必要があります。

public void onPreviewFrame(byte[] yuvArray, Camera camera) {
...
  camera.addCallbackBuffer(callbackBuffer);
...
}

ByteBuffer.wrap()GL呼び出しでメモリを割り当てているという最初の疑いに対処するために:そうではありません。実際には (yArray提供されたコード内の) 基礎となる配列を使用し、ガベージ コレクションのために新しいメモリを割り当てません。

于 2012-07-10T18:10:48.323 に答える
0

呼び出しごとに新しいByteBufferインスタンスを作成していonDrawFrameますが、これはすぐにガベージおよびコレクションされます。これは、データのサイズが変更され、テクスチャ サイズ自体が変更された場合にのみ必要です。これはありそうにないと思います。

1 回を事前に割り当て、ByteBuffer一括メソッドでそのコンテンツを更新します。

于 2012-07-10T05:25:25.257 に答える