ronag
ronag

Reputation: 51255

Why am I getting E_OUTOFMEMORY?

For some reason the code below will give me a out of memory error. What am I missing?

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

Upvotes: 4

Views: 8706

Answers (3)

Ross Ridge
Ross Ridge

Reputation: 39581

It turns out that catflier provided the answer to this question in a comment:

release does not release immediately, and since on the code there's no calls it will never do it. Calling either devicecontext Flush method or some swapchain present (which will flush the device) will cause the resource deletion

Upvotes: 2

Alessandro Jacopson
Alessandro Jacopson

Reputation: 18603

Maybe it is not your case but, for example, Microsoft's COM method CComObject::CreateInstance can return E_OUTOFMEMORY (at least in the implementation I can found in my environment, i.e. Visual Studio 2012) and in my opinion it can be misleading.

The COM method is something like the following (in 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()

and it seems to me that the above code can return E_OUTOFMEMORY even if you have a lot of memory still available: the macro ATLTRY just wraps the call to new in a try-catch(...) block and so if the constructor of Base fails throwing an exception, any kind of exception even not related to memory issues, then p will be NULL and the function will return E_OUTOFMEMORY.

Upvotes: 2

DNT
DNT

Reputation: 2395

Just an idea, but have you considered this: 1920 * 1080 * 32bits = 8294400 bytes Now, 8294400 bytes x 485 textures = 3.836 GBytes of memory. This is right at the limit of a 32bit machine. I don't know if you are coding a 32 or 64 bit program, but if it is 32bit then the maximum virtual memory you can address is a little under 4GB and 512 textures take you over this limit. Considering that Release does not free up this memory immediately, and if you are actually coding in 32bit, then it should be clear why you run out of memory.

Upvotes: 2

Related Questions