Я имею в виду немного странный сценарий, но это именно то, что я планировал создать. Это просто особый вид тестирования программного обеспечения …
Моя среда: MSVS 2012, Windows 7/8 32b / 64b.
Итак, сначала я создаю некоторые внутренние структуры / буферы / и т.д. для использования в моем приложении, затем я делаю что-то вроде этого (здесь немного упрощено, пожалуйста, относитесь к нему скорее как к псевдокоду):
{
std::deque<boost::scoped_array<unsigned char>> deque;
try {
while (1) {
deque.push_back(boost::scoped_array<unsigned char>(new unsigned char[system_page_size])); // happens to be 4096 on my system
}
}
catch (std::bad_alloc& ex) { ... }
// do something here
}
Мне нужно использовать как можно больше памяти. Я выделяю целые страницы одновременно (может быть, это плохо и должно оставить место для данных deque / smart ptr?). Когда CRT решит, что выделение больше невозможно, я сделаю еще кое-что (не полагаясь на доступность памяти) и выйду из области. Это вызовет цепочку деструкторов, и все эти данные должны быть освобождены.
Это прекрасно работает. Но я случайно вхожу в эту странную область не один, а 10 раз подряд. Иногда это работает 2 или 3 раза. Иногда только один раз. В следующий раз вылезу только ошибки памяти и все.
С моей точки зрения, мне нужно перезапустить весь процесс, чтобы действительно заставить память освободиться. Есть ли способ достичь этого в одном процессе?
Я могу подумать о разных распределителях — может быть, это проблема CRT? Я также немного поиграл с манипуляциями с кучей (то есть с низкой кучей фрагментации), но тоже не помог.
Почему бы не зарезервировать все пространство памяти вашего процесса с несколькими большими VirtualAlloc звонки с использованием MEM_RESERVE. Затем вы будете вызывать VirtualFree позже для каждого диапазона памяти для освобождения. Это по-прежнему требует некоторого выделения кучи, как вы делаете здесь, чтобы исчерпать оставшуюся часть вашей текущей кучи. Это будет быстрее и уберет отток файла подкачки, который вы должны испытывать.
Что касается вашей конкретной проблемы, я не знаю, почему вы испытываете это. Резервирование всей памяти, чтобы куча не могла расширяться, должно помочь уменьшить недетерминизм.
Если вы используете БОЛЬШИЕ объемы памяти, используете какое-то распределение блоков (VirtualAlloc предоставит вам память для этого), а затем, в принципе [предполагается, что объектам, созданным в этом блоке, не нужен деструктор, чтобы что-то делать] Вы можете просто отбросить весь блок за один раз, вместо того, чтобы удалять gazillion раз — с дополнительным преимуществом экономии времени и гарантии того, что ваша память была полностью освобождена.
Я подозреваю, что одна из причин, по которой у вас могут возникнуть проблемы, заключается в том, что освобожденные блоки должны быть очищены, прежде чем они могут быть переработаны. Это делается в фоновом потоке в ядре. Конечно, использование VirtualALloc не поможет в этом случае.
Конечно, также возможно, что вы получите фрагментацию памяти, в этом случае использование головки, предназначенной для избежания этого, сработает.