Поддерживает ли FastMM резервирование виртуальной памяти и вызовы фрагментами для увеличения массива?

Я знаю, что могу зарезервировать виртуальную память с помощью VirtualAlloc.
например. Я могу потребовать 1 ГБ виртуальной памяти, а затем вызвать первый из них, чтобы поместить в него растущий массив.
Когда размер массива превысит 1 МБ, я вызову второй МБ и так далее.
Таким образом, я не мне не нужно перемещать массив в памяти, когда он растет, он просто остается на месте, а менеджер виртуальной памяти Intel/AMD позаботится обо всех моих проблемах.

Однако поддерживает ли FastMM эту структуру, поэтому мне не нужно самостоятельно управлять памятью?

Псевдокод:

type
  PBigarray = ^TBigarray;
  TBigArray = array[0..0] of SomeRecord;

....

begin
  VirtualMem:= FastMM.ReserveVirtualMemory(1GB);
  PBigArray:= FastMM.ClaimPhysicalMemory(VirtualMem, 1MB);
....

procedure GrowBigArray
begin
  FastMM.ClaimMorePhysicalMemory(PBigArray, 1MB {extra});
  //will generate OOM exception when claim exceeds 1GB

Поддерживает ли FastMM это?


person Johan    schedule 17.06.2011    source источник
comment
Это имеет признаки XY-проблемы. Я догадываюсь о ваших реальных проблемах, но я подозреваю, что вы страдаете от фрагментации адресного пространства, потому что ваш код требует больших смежных блоков памяти. Если это так, то лучшим решением будет выделить несмежные блоки, а затем собрать их вместе за кулисами, чтобы эти меньшие блоки выглядели как непрерывный блок.   -  person David Heffernan    schedule 17.06.2011
comment
То, о чем вы просите, - это узкоспециализированное поведение, которое легко обрабатывается с помощью VirtualAlloc; Зачем это делать универсальному диспетчеру памяти?   -  person Cosmin Prund    schedule 17.06.2011
comment
@ Дэвид, спасибо, что присматриваешь за мной. У меня еще нет фрагментации памяти, потому что я еще не написал программу :-). Я знаю, что у меня есть программа, которая будет использовать всю доступную память, поэтому я изучаю варианты. Это не превратится в длинные вопросы и ответы, подойдет простое да/нет, и я предполагаю, что это нет.   -  person Johan    schedule 17.06.2011
comment
@Johan Да, я думаю, что нет, это ответ. Я могу помочь вам с проблемой фрагментации адресного пространства, когда вы приступите к написанию программы. Надеюсь, вы хорошо знаете IMAGE_LARGE_ADDRESS_AWARE.   -  person David Heffernan    schedule 17.06.2011
comment
@ Дэвид, я не знал, что это так называется, но я знал, что вы можете попросить Windows предоставить вам больше виртуальной памяти.   -  person Johan    schedule 17.06.2011
comment
Очень распространено заблуждение, что при фиксации (VirtualAlloc с MEM_COMMIT) используется любая физическая память. Это. Делает. Нет. Все, что он делает, это увеличивает общий счетчик выделенной памяти ОС, и если он теперь больше, чем общая физическая память + общий размер файла подкачки, ОС начнет увеличивать файл подкачки в ожидании, что он может понадобиться позже. Но пока нет никакой физической памяти, связанной с этим распределением. Только когда к рассматриваемой памяти фактически осуществляется доступ, ОС будет назначать пустые страницы из пула обнуленных страниц постранично по мере необходимости.   -  person Thorsten Engler    schedule 17.06.2011
comment
@Johan, обратите внимание, что использование AWE означает, что в ОС меньше доступной памяти, и это может означать, что она замедляется. Не такая уж большая проблема, если у вас есть выделенная машина, но может быть существенной на машинах, на которых одновременно запущено несколько служб/приложений.   -  person Marjan Venema    schedule 17.06.2011
comment
@Marjan Venema, я не думаю, что Йохан говорил об AWE, с просьбой предоставить вам больше виртуальной памяти, он, вероятно, имел в виду переключатель / 3GB в 32-битных окнах или просто запускал приложение Win32 в 64-битных окнах. (что дает полные 4 ГБ, в обоих случаях при условии, что используется IMAGE_LARGE_ADDRESS_AWARE)   -  person Thorsten Engler    schedule 17.06.2011
comment
@Thorsten: извините, я продолжаю ошибаться в аббревиатурах в этой области. Я имел в виду этот надоедливый переключатель /3GB, поскольку он (на Win32) оставляет ОС только 1GB вместо 2GB, чтобы выполнять свои собственные действия.   -  person Marjan Venema    schedule 17.06.2011
comment
@Марьян Венема, а, хорошо. Тогда я полностью согласен, переключатель /3GB во многих случаях приносит больше вреда, чем пользы. Но сегодня это практически неактуально. Какая более новая система работает под управлением 32-битной версии Windows в наши дни? А при работе (как программа Win32) под 64-битной версией Windows вы получаете не просто 3 ГБ, а полное адресное пространство 4 ГБ, без недостатков, используя флаг IMAGE_LARGE_ADDRESS_AWARE.   -  person Thorsten Engler    schedule 17.06.2011


Ответы (1)


Нет, FastMM4 (последняя версия, которую я смотрел) явно не поддерживает это. Это действительно не та функциональность, которую вы ожидаете от диспетчера памяти общего назначения, поскольку это тривиально просто сделать с помощью вызовов VirtualAlloc.

NexusMM4 (который является частью NexusDB) делает то, что дает вам аналогичный результат, но не тратит впустую все адресное пространство до того, как оно понадобится в фоновом режиме.

Если вы делаете первоначальное большое выделение (напрямую через GetMem или косвенно через динамический массив или что-то подобное), память выделяется только в необходимом размере через VirtualAlloc.

Но если это распределение затем будет изменено на больший размер, NexusMM будет использовать другой способ выделения памяти, который позволяет ему просто отменить выделение из адресного пространства и переназначить его снова, с большим размером, когда произойдет дальнейшее перераспределение.

Это предотвращает две основные проблемы, с которыми сталкиваются большинство менеджеров памяти общего назначения при перераспределении:

  • во время обычного перераспределения существующее и новое выделение должны присутствовать в адресном пространстве одновременно, что временно удваивает требования к адресному пространству и физической памяти.
  • во время обычного перераспределения необходимо скопировать все содержимое существующего распределения

Таким образом, с NexusMM вы получите все преимущества того, что вы показали в своем псевдокоде (за исключением того, что первый realloc будет включать копию, и что увеличение вашего массива может изменить его адрес), просто используя обычные вызовы GetMem/ReallocMem/FreeMem .

person Thorsten Engler    schedule 17.06.2011