There is no such thing as a "2MB program".... all you have is a program composed of <=64K segments, which are easy enough to fit into the hole.
If you do need something approaching a 2MB block of memory, you don't need a contiguous range of memory, what you need is a contiguous range of selectors, which is a different (and probably easier) problem to solve.
but without virtual memory you can't move them around and so program that wants to allocate 2MB of 64k segments can't run if there is no 2MB continuos hole