Why am I getting E_OUTOFMEMORY?

For some reason, the code below will give me an error in memory. 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(); } 
+4
source share
3 answers

Just an idea, but you thought it: 1920 * 1080 * 32 bit = 8294400 bytes Now 8294400 bytes x 485 textures = 3.836 GB of memory. This is correct at the limit of a 32-bit machine. I don’t know if you are coding a 32-bit or 64-bit program, but if it is 32-bit, then the maximum virtual memory that you can solve is slightly less than 4 GB, and 512 textures will overcome this limit. Given that Release does not free this memory immediately, and if you are actually encoding 32-bit, it should be clear why you ran out of memory.

+2
source

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

the release is not released immediately, and since there is no ringing on the code, it will never do so. Calling the devicecontext Flush method or some swapchain (which will hide the device) will result in resource deletion

+2
source

Perhaps this is not your case, but, for example, the Microsoft COM CComObject::CreateInstance method can return E_OUTOFMEMORY (at least in the implementation I can find in my environment, that is, Visual Studio 2012), and, in my opinion, it can mislead.

The COM method is similar to 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 available: the ATLTRY macro just ends the new call in try-catch (...), and therefore, if the Base constructor does not throw an exception, any exception will even not related to memory issues, then p will be NULL and the function will return E_OUTOFMEMORY .

+1
source

All Articles