C# で記述された XNA 4.0 アプリケーションでメモリ リークが見つかりました。プログラムは長時間 (数日) 実行する必要がありますが、数時間かけてメモリが不足し、クラッシュします。タスク マネージャーを開いてメモリ フットプリントを確認すると、プログラムがなくなるまで毎秒 20 ~ 30 KB のメモリがプログラムに割り当てられます。プロパティを設定すると、最終的に例外BasicEffect.Texture
をスローするステートメントであるため、メモリリークが発生すると思います。OutOfMemory
このプログラムには約 300 個の大きな (512px) テクスチャが Texture2D オブジェクトとしてメモリに格納されています。テクスチャは正方形ではなく、2 のべき乗でもありません。これらのオブジェクトは初期化時にのみ作成されるため、Texture2D オブジェクトを動的に作成/破棄することによって引き起こされたものではないと確信しています。一部のインターフェイス要素は独自のテクスチャを作成しますが、コンストラクター内でのみ作成され、これらのインターフェイス要素がプログラムから削除されることはありません。
テクスチャ マップされた三角形をレンダリングしています。各オブジェクトを三角形でレンダリングする前に、BasicEffect.Texture
プロパティを作成済みのTexture2D
オブジェクトに設定し、BasicEffect.TextureEnabled
プロパティを に設定しますtrue
。BasicEffect
これらの各呼び出しの間に を適用します-必要な 2 倍のBasicEffect.CurrentTechnique.Passes[0].Apply()
呼び出しを行っていることは承知していますが、コードはのプロパティが変更されるたびに呼び出すヘルパー クラス内にラップされています。Apply()
Apply()
BasicEffect
BasicEffect
アプリケーション全体で1 つのクラスを使用しており、そのプロパティを変更しApply()
て、オブジェクトをレンダリングするたびに呼び出すようにしています。
まず、プロパティを変更して何度もBasicEffect.Texture
呼び出すと、メモリ リークが発生する可能性があります。Apply()
第二に、これは異なるテクスチャで三角形をレンダリングする適切な方法ですか? たとえば、シングルBasicEffect
を使用してそのプロパティを更新しますか?
このコードはヘルパー クラスから取得したものなので、すべての綿毛を取り除き、関連する XNA 呼び出しのみを含めました。
//single BasicEffect object for entire application
BasicEffect effect = new BasicEffect(graphicsDevice);
// loaded from file at initialization (before any Draw() is called)
Texture2D texture1 = new Texture2D("image1.jpg");
Texture2D texture2 = new Texture2D("image2.jpg");
// render object 1
if(effect.Texture != texture1) // effect.Texture eventually throws OutOfMemory exception
effect.Texture = texture1;
effect.CurrentTechnique.Passes[0].Apply();
effect.TextureEnabled = true;
effect.CurrentTechnique.Passes[0].Apply();
graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices1, 0, numVertices1, indices1, 0, numTriangles1);
// render object 2
if(effect.Texture != texture2)
effect.Texture = texture2;
effect.CurrentTechnique.Passes[0].Apply();
effect.TextureEnabled = true;
effect.CurrentTechnique.Passes[0].Apply();
graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices2, 0, numVertices2, indices2, 0, numTriangles2);
これは XNA アプリケーションなので、1 秒あたり 60 回、Draw メソッドを呼び出します。これにより、さまざまなインターフェイス要素がすべてレンダリングされます。これは、フレームごとに 100 ~ 200 のテクスチャを描画できることを意味し、描画するテクスチャが増えるほどnew
、更新/描画ループのどこにも呼び出しを行っていないにもかかわらず、メモリ不足が速くなります。私は DirectX よりも OpenGL の経験が豊富なので、明らかに、私が気付いていない管理されていないメモリを作成している舞台裏で何かが起こっています。