docs: public void release(Collection<MemorySegment> segments) {
  		if (segments == null) {
  			return;
  		}
  
  		// -------------------- BEGIN CRITICAL SECTION -------------------
  		synchronized (lock) {
  			if (isShutDown) {
  				throw new IllegalStateException("Memory manager has been shut down.");
  			}
  
  			// since concurrent modifications to the collection
  			// can disturb the release, we need to try potentially multiple times
  			boolean successfullyReleased = false;
  			do {
  				final Iterator<MemorySegment> segmentsIterator = segments.iterator();
  
  				Object lastOwner = null;
  				Set<MemorySegment> segsForOwner = null;
  
  				try {
  					// go over all segments
  					while (segmentsIterator.hasNext()) {
  
  						final MemorySegment seg = segmentsIterator.next();
  						if (seg == null || seg.isFreed()) {
  							continue;
  						}
  
  						final Object owner = seg.getOwner();
  
  						try {
  							// get the list of segments by this owner only if it is a different owner than for
  							// the previous one (or it is the first segment)
  							if (lastOwner != owner) {
  								lastOwner = owner;
  								segsForOwner = this.allocatedSegments.get(owner);
  							}
  
  							// remove the segment from the list
  							if (segsForOwner != null) {
  								segsForOwner.remove(seg);
  								if (segsForOwner.isEmpty()) {
  									this.allocatedSegments.remove(owner);
  								}
  							}
  
  							if (isPreAllocated) {
  								memoryPool.returnSegmentToPool(seg);
  							}
  							else {
  								seg.free();
  								numNonAllocatedPages++;
  							}
  						}
  						catch (Throwable t) {
  							throw new RuntimeException(
  									"Error removing book-keeping reference to allocated memory segment.", t);
  						}
  					}
  
  					segments.clear();
  
  					// the only way to exit the loop
  					successfullyReleased = true;
  				}
  				catch (ConcurrentModificationException | NoSuchElementException e) {
  					// this may happen in the case where an asynchronous
  					// call releases the memory. fall through the loop and try again
  				}
  			} while (!successfullyReleased);
  		}
  		// -------------------- END CRITICAL SECTION -------------------
  	}