記憶がどのように流れるかについて、しかし、私は理由を理解できませんでした

こんにちは、habracheloveki様。

この短い投稿では、アプリケーション(Windowsのリーダー)の開発中に出会ったいくつかのポイントを共有したいと思います。 これはDirectXについてのもので、奇妙なメモリリークのように思えました。

自分で問題を作成するにはどうすればよいですか?


ページのコンテンツを表示するには、DirectXを使用することにしました。 アイデアはシンプルでした。最初にテキストで2Dテクスチャを作成し、次に事前に準備したテクスチャを使用して3Dモデルを表示します。 これにより、3Dページめくりアニメーションを行うことができます。

このようなもの:



ストアへのアプリケーションのリリースの時点で、私は普遍的な賞賛を期待していました。 しかし、そこにありました。 ユーザーは不満でした。 状況の分析は、記憶が流れていることを示しました。 そして、非常によく流れます。 しかし、なぜですか? これは長い間理解できませんでした。
Windows 8.1およびWindows Phone 8.1のアプリケーションが「クローズ」中に完全にアンロードされないという事実を考えると、メモリリークが蓄積されました。

漏れを見つけるプロセスはまったく面白くありませんでした。 しかし、結果は私には奇妙に思えました。

私にとって奇妙に思えたのは何ですか?


レンダーターゲットリソース(翻訳方法がわからない)と深度バッファの解放


次のオブジェクトは、3Dシーンの1つのフレームを表示するために使用されます。

Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_renderTargetView; Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_depthStencilView; 

さらに、シーン表示メソッドのどこかで、次のコードのようなものを使用します。

 ID3D11RenderTargetView *const targets[1] = { m_renderTargetView.Get() }; m_d3dContext->OMSetRenderTargets(1, targets, m_depthStencilView.Get()); 

リソースを解放する必要があります。 そして、この投稿の原因となった問題の1つが潜んでいます。
書くだけ:

 m_renderTargetView = nullptr; m_depthStencilView = nullptr; 

十分ではありません。 内部のm_d3dContextには、レンダーターゲットと深度バッファーへのリンクがあります。
つまり 目標としてコンテキストに何も示す必要はありません。

 m_d3dContext->OMSetRenderTargets(0, nullptr, nullptr); 

問題は、次のようにするとメモリリークが発生することです。

 m_d3dContext->OMSetRenderTargets(0, nullptr, nullptr); m_renderTargetView = nullptr; m_depthStencilView = nullptr; 

状況を修正するには、指示の順序を変更するだけです。

 m_renderTargetView = nullptr; m_depthStencilView = nullptr; m_d3dContext->OMSetRenderTargets(0, nullptr, nullptr); 

これは私が理解していない最初の「奇異」です。 誰かがこれが起こる理由を教えてくれたら嬉しいです。

テクスチャリソースリリース


2番目の「奇異」はテクスチャに関連しています。 または、シェーダーリソースを使用します。
事実は、これが好きなら:

 Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> texture = ... m_d3dContext->PSSetShaderResources(0, 1, &texture); 

そうする必要があります:

 ID3D11ShaderResourceView* empty = NULL; d3dContext->PSSetShaderResources(0, 1, &empty); 

そうしないと、テクスチャを「削除」しても、テクスチャは解放されません。

 texture = nullptr; 

つまり、シェーダーリソースを削除(リリース)する前に、それらを解放(バインド解除)する必要があります。

原則として、最初の「奇妙さ」を実現した後、2番目はもはやそうではないようです。
それにもかかわらず、これは私には明らかではないようでした。

PS:現在、メモリリークの問題は修正されており、ユーザーの怒りは徐々に慈悲に変わっています。

Source: https://habr.com/ru/post/J242893/


All Articles