/** * 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 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()); } }