由于某种原因,下面的代码会给我一个内存不足的错误。我错过了什么?
for(int n = 0; n < 512; ++n)
{
D3D11_TEXTURE2D_DESC texture_desc = {};
texture_desc.Width = 1920;
texture_desc.Height = 1080;
texture_desc.MipLevels = 1;
texture_desc.ArraySize = 1;
texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
texture_desc.SampleDesc.Count = 1;
texture_desc.Usage = D3D11_USAGE_DEFAULT;
texture_desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
ID3D11Texture2D* target_d3d_ptr;
HRESULT hr = this->device_ptr->CreateTexture2D(&texture_desc, nullptr, &target_d3d_ptr);
if(FAILED(hr))
throw runtime_error(_com_error(hr).ErrorMessage());
target_d3d_ptr->Release();
}
答案 0 :(得分:2)
只是一个想法,但你考虑过这个: 1920 * 1080 * 32bits = 8294400字节 现在,8294400字节x 485纹理= 3.836 GB内存。 这是在32位机器的极限。我不知道你是在编写一个32位还是64位的程序,但如果它是32位,那么你可以解决的最大虚拟内存略低于4GB,512个纹理会超过这个限制。考虑到Release不会立即释放这个内存,如果你实际上是在32位编码,那么应该清楚为什么你的内存不足。
答案 1 :(得分:2)
也许不是你的情况,但是,例如,Microsoft的COM方法CComObject::CreateInstance
可以返回E_OUTOFMEMORY
(至少在我的环境中可以找到的实现中,即Visual Studio 2012 )在我看来,这可能会产生误导。
COM方法类似于以下内容(在atlcom.h
)
ATLPREFAST_SUPPRESS(6387)
template <class Base>
_Success_(return == S_OK) HRESULT WINAPI CComObject<Base>::CreateInstance(
_Deref_out_ CComObject<Base>** pp) throw()
{
// code omitted
HRESULT hRes = E_OUTOFMEMORY;
CComObject<Base>* p = NULL;
ATLTRY(p = new CComObject<Base>())
if (p != NULL)
{
// code omitted
}
*pp = p;
return hRes;
}
ATLPREFAST_UNSUPPRESS()
在我看来,即使您仍有大量内存,上述代码也可以返回E_OUTOFMEMORY
:宏ATLTRY
只是试一试new
-catch(...)阻止所以如果Base
的构造函数未能抛出异常,任何类型的异常甚至与内存问题无关,那么p
将是NULL
,该函数将返回E_OUTOFMEMORY
。
答案 2 :(得分:2)
事实证明,catflier在评论中提供了这个问题的答案:
发布不会立即释放,因为在代码上没有 打电话它永远不会这样做。调用devicecontext
Flush
方法 或者一些交换链存在(将刷新设备)将导致 资源删除