@Override public <T extends MemorySegment> void release(Collection<T> segments) { // sanity checks if (segments == null) { return; } // -------------------- BEGIN CRITICAL SECTION ------------------- synchronized (this.lock) { if (this.isShutDown) { throw new IllegalStateException("Memory manager has been shut down."); } final Iterator<T> segmentsIterator = segments.iterator(); AbstractInvokable lastOwner = null; Set<DefaultMemorySegment> segsForOwner = null; // go over all segments while (segmentsIterator.hasNext()) { final MemorySegment seg = segmentsIterator.next(); if (seg.isFreed()) { continue; } final DefaultMemorySegment defSeg = (DefaultMemorySegment) seg; final AbstractInvokable owner = defSeg.owner; 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(defSeg); if (segsForOwner.isEmpty()) { this.allocatedSegments.remove(owner); } } } catch (Throwable t) { LOG.error("Error removing book-keeping reference to allocated memory segment.", t); } finally { // release the memory in any case byte[] buffer = defSeg.destroy(); this.freeSegments.add(buffer); } } segments.clear(); } // -------------------- END CRITICAL SECTION ------------------- }
@Override public void release(MemorySegment segment) { // check if segment is null or has already been freed if (segment == null || segment.isFreed() || !(segment instanceof DefaultMemorySegment)) { return; } final DefaultMemorySegment defSeg = (DefaultMemorySegment) segment; final AbstractInvokable owner = defSeg.owner; // -------------------- BEGIN CRITICAL SECTION ------------------- synchronized (this.lock) { if (this.isShutDown) { throw new IllegalStateException("Memory manager has been shut down."); } // remove the reference in the map for the owner try { Set<DefaultMemorySegment> segsForOwner = this.allocatedSegments.get(owner); if (segsForOwner != null) { segsForOwner.remove(defSeg); if (segsForOwner.isEmpty()) { this.allocatedSegments.remove(owner); } } } catch (Throwable t) { LOG.error("Error removing book-keeping reference to allocated memory segment.", t); } finally { // release the memory in any case byte[] buffer = defSeg.destroy(); this.freeSegments.add(buffer); } } // -------------------- END CRITICAL SECTION ------------------- }