Как отмечается в комментариях, нет уверенности в том, что, хотя сборщик мусора удаляет объекты, он возвращает память системе.
Возможно Настройка схемы сбора мусора предоставляет решение вашей проблемы:
По умолчанию JVM увеличивает или уменьшает кучу в каждом GC, чтобы сохранить соотношение свободного пространства и живых объектов в каждой коллекции в пределах указанного диапазона.
-XX:MinHeapFreeRatio
- когда процент свободного пространства в поколении падает ниже этого значения, поколение будет расширено, чтобы соответствовать этому проценту. По умолчанию 40
-XX:MaxHeapFreeRatio
- когда процент свободного пространства в поколении превысил это значение, поколение будет сокращаться для достижения этого значения. По умолчанию 70
В противном случае, если вы подозреваете, что у вас есть утечка ссылок, вы можете выяснить, как, что и куда просачиваются объекты, это контролировать кучу в JVisualVM (инструмент, входящий в комплект стандартного SDK). С помощью этой программы вы можете выполнить дамп кучи и получить гистограмму об использовании памяти объекта: