Since some time UtilCache has been updated to replace the WeakHashMap by a ConcurrentHashMap:
private static final ConcurrentHashMap<String, UtilCache<?, ?>> utilCacheTable = new ConcurrentHashMap<String, UtilCache<?, ?>>();
I think this fix to concurrency issues has introduced a memory leak or at least a much bigger impact on Memory.
Indeed descendent of AbstractCache (particularly AbstractEntityConditionCache, EntityListCache) tend to create many caches that do not need to always persist in time.
The old WeakHashMap handled this by enabling them to disappear while today the Hard ref disables this.