为什么我得到E_OUTOFMEMORY?

时间:2013-01-19 18:36:01

标签: c++ winapi visual-studio-2012 direct3d

由于某种原因,下面的代码会给我一个内存不足的错误。我错过了什么?

    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();
    }

3 个答案:

答案 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方法   或者一些交换链存在(将刷新设备)将导致   资源删除