/** Free a block of memory allocated via {@link TaskMemoryManager#allocatePage(long)}. */ public void freePage(MemoryBlock page) { assert (page.pageNumber != -1) : "Called freePage() on memory that wasn't allocated with allocatePage()"; executorMemoryManager.free(page); synchronized (this) { allocatedPages.clear(page.pageNumber); } pageTable[page.pageNumber] = null; if (logger.isTraceEnabled()) { logger.trace("Freed page number {} ({} bytes)", page.pageNumber, page.size()); } }
/** * Clean up all allocated memory and pages. Returns the number of bytes freed. A non-zero return * value can be used to detect memory leaks. */ public long cleanUpAllAllocatedMemory() { long freedBytes = 0; for (MemoryBlock page : pageTable) { if (page != null) { freedBytes += page.size(); freePage(page); } } final Iterator<MemoryBlock> iter = allocatedNonPageMemory.iterator(); while (iter.hasNext()) { final MemoryBlock memory = iter.next(); freedBytes += memory.size(); // We don't call free() here because that calls Set.remove, which would lead to a // ConcurrentModificationException here. executorMemoryManager.free(memory); iter.remove(); } return freedBytes; }
/** Free memory allocated by {@link TaskMemoryManager#allocate(long)}. */ public void free(MemoryBlock memory) { assert (memory.pageNumber == -1) : "Should call freePage() for pages, not free()"; executorMemoryManager.free(memory); final boolean wasAlreadyRemoved = !allocatedNonPageMemory.remove(memory); assert (!wasAlreadyRemoved) : "Called free() on memory that was already freed!"; }