private DataBuffer getCacheBuffer() throws IOException {

		// Create new buffer if cache not fully allocated
		if (cacheSize < maxCacheSize) {
			++cacheSize;
			lowWaterMark = cacheSize;
			return new DataBuffer(cacheFile.getBufferSize());
		}

		// Use buffer from free stack if available
		if (!freeBuffers.isEmpty()) {
			--buffersOnHand;
			if (buffersOnHand < lowWaterMark) {
				lowWaterMark = buffersOnHand;
			}
			return freeBuffers.pop();
		}

		// Get oldest buffer node in cache
		BufferNode oldNode = cacheTail.prevCached;
		if (oldNode.id == HEAD) {
			// cache limit has been exceeded
			throw new IOException("Out of cache buffer space");
		}

		// Unload buffer from memory cache
		DataBuffer buf = oldNode.buffer;
		unloadCachedNode(oldNode);
		removeFromCache(oldNode);

		return buf;
	}
Get a reusable buffer object from cache.
The oldest buffer node is removed from memory cache.
@return buffer object.
@throws IOException if a cache file access error occurs
Ghidra/Framework/DB/src/main/java/db/buffers/BufferMgr.java