Это очень верно. Процесс должен выделять память из адресного пространства виртуальной памяти. В котором хранятся код и данные и размер которых ограничен возможностями адресации архитектуры. Вы никогда не сможете адресовать более 2^32 байта в 32-битном процессе, не считая трюков с банковской коммутацией. Это 4 гигабайта. Операционная система обычно вынимает большой кусок из этого же, в 32-битной Windows, например, который сокращает адресный размер виртуальной машины до 2 гигабайт.
В идеале, ассигнования производятся таким образом, чтобы они плотно прилегали друг к другу. Это очень редко получается на практике. В общих библиотеках или DLL, в частности, необходимо выбрать предпочтительный адрес загрузки, и это нужно угадывать спереди, когда библиотека построена.
Таким образом, на практике ассигнования производятся из отверстий между существующими и максимально возможными смежным Распределение, которое вы можете получить, ограничено размером с наибольшим отверстием. Обычно намного меньше адресного размера VM, в Windows обычно около 650 мегабайт. То, что имеет тенденцию идти вниз-холм оттуда, поскольку доступное адресное пространство получает фрагментировано распределениями. В частности, с помощью собственного кода, который не может позволить себе распределений, перемещаемых уплотняющим сборщиком мусора. Если вы используете Windows, вы можете получить представление о распределении VM с помощью утилиты VMMap SysInternals.
Эта проблема полностью исчезает в 64-битном процессе. Теоретический адресный объем виртуальной памяти составляет 2^64, огромное количество. Настолько большие, что текущие процессоры не реализуют его, они могут достигать 2^48. Кроме того, вы ограничены версией операционной системы и ее готовностью хранить таблицы сопоставления страниц для этой большой виртуальной машины. Типичный предел - восемь терабайт. Подразумевается, что отверстия между распределениями являются огромными. Ваша программа будет зависеть от файла пейджинга, прежде чем он умрет от OOM.