По какой-то причине приведенный ниже код выдаст мне ошибку нехватки памяти. Что мне не хватает?
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();
}
Просто идея, но вы рассматривали это:
1920 * 1080 * 32 бит = 8294400 байт
Теперь 8294400 байт x 485 текстур = 3,836 ГБ памяти.
Это прямо на пределе 32-битной машины. Я не знаю, кодируете ли вы 32- или 64-битную программу, но если она 32-битная, то максимальная виртуальная память, на которую вы можете адресовать, составляет чуть менее 4 ГБ, и 512 текстур забирают вас за этот предел. Учитывая, что Release не освобождает эту память немедленно, и если вы на самом деле кодируете в 32-битном, тогда должно быть понятно, почему у вас не хватает памяти.
Может быть, это не ваш случай, но, например, метод COM от Microsoft 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
в блоке try-catch (…) и так, если конструктор Base
не выбрасывает исключение, любой вид исключения, даже не связанный с проблемами памяти, то p
будет NULL
и функция вернется E_OUTOFMEMORY
,
Оказывается, что catflier предоставил ответ на этот вопрос в комментарии:
релиз не выпускает сразу, а так как в коде нет
звонки это никогда не сделает Вызов любого устройстваFlush
метод
или наличие какого-либо swapchain (который очистит устройство) вызовет
удаление ресурса