Во-первых, в jvm это как-то работает. Магии же не бывает, они тоже в оперативной памяти как-то перетаскивают куски памяти.
Во-вторых, тут как бы не только в освобождении дело, тут ещё и в выделении проблема тоже. Представьте ситуацию, что у вас память фрагментирована на маленькие куски. Причём 20 GB пяти свободно, но вы не можете в них выделить 10MB, потому что фрагметация памяти и невозможно найти непрерывный кусок такого размера.
Сама ОС умеет эту проблему решать, т.е. когда ей надо выделить память, а у неё всё фрагментировано, она как-то умеет перемещать (только то, что возможно переместить), чтобы выделить память.
А вот если ваш язык программирования забрал всю память (к примеру 40Gb, но реально используется только 20GB) и она расположена так, что сам язык программирования не может выделть каких-то 10MB, то это по-моему проблема.
Вспоминается по этой теме приблуда memturbo из виндов 9x, которая делала дефрагментацию виндусовой памяти.