I am surprised. Doesn't a current high-grade OS like Linux (maybe not Windows) routinely close the gaps in RAM by relocating running code and data? This is quite efficiently do-able in CPU architectures that use base/index/displacement memory addressing in the instruction set. This was introduced in the IBM 360 in 1964, carried forward into Intel x86, and probably used everywhere else since then.
With base/index/displacement memory addressing, running code and data can easily be relocated by copying it to the new location and changing the contents of a few base registers, unlike the older architecture of entire linear addresses stored in the instructions that would require the whole program and data to have its addresses adjusted/rewritten after relocation.
(Yes, if this sounds "academic", I have an M.Sc. (1975) in computer science.) :)