From 002c97d07268d2aa98c22f52e6a66edfc42e7a81 Mon Sep 17 00:00:00 2001 From: spricoder Date: Sat, 25 Jan 2025 17:14:28 +0800 Subject: [PATCH] add comment and optimize code --- .../apache/iotdb/db/conf/IoTDBDescriptor.java | 59 +++-- .../resource/memory/PipeMemoryManager.java | 2 +- .../metrics/memory/GlobalMemoryMetrics.java | 2 - .../memory/StorageEngineMemoryMetrics.java | 6 +- .../LoadTsFileDataCacheMemoryBlock.java | 2 +- .../load/memory/LoadTsFileMemoryManager.java | 2 +- .../cache/TableDeviceSchemaCacheTest.java | 6 +- .../iotdb/commons/memory/IMemoryBlock.java | 6 +- .../iotdb/commons/memory/MemoryBlock.java | 4 +- .../iotdb/commons/memory/MemoryBlockType.java | 2 + .../iotdb/commons/memory/MemoryManager.java | 239 +++++++++++++----- 11 files changed, 219 insertions(+), 111 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java index dccd148b7b66..3f4301c09899 100755 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java @@ -2216,23 +2216,23 @@ private void initMemoryAllocate(TrimProperties properties) { } // storage engine memory manager MemoryManager storageEngineMemoryManager = - globalMemoryManager.createMemoryManager("StorageEngine", storageEngineMemorySize); + globalMemoryManager.getOrCreateMemoryManager("StorageEngine", storageEngineMemorySize); conf.setStorageEngineMemoryManager(storageEngineMemoryManager); // query engine memory manager MemoryManager queryEngineMemoryManager = - globalMemoryManager.createMemoryManager("QueryEngine", queryEngineMemorySize); + globalMemoryManager.getOrCreateMemoryManager("QueryEngine", queryEngineMemorySize); conf.setQueryEngineMemoryManager(queryEngineMemoryManager); // schema engine memory manager MemoryManager schemaEngineMemoryManager = - globalMemoryManager.createMemoryManager("SchemaEngine", schemaEngineMemorySize); + globalMemoryManager.getOrCreateMemoryManager("SchemaEngine", schemaEngineMemorySize); conf.setSchemaEngineMemoryManager(schemaEngineMemoryManager); // consensus layer memory manager MemoryManager consensusMemoryManager = - globalMemoryManager.createMemoryManager("Consensus", consensusMemorySize); + globalMemoryManager.getOrCreateMemoryManager("Consensus", consensusMemorySize); conf.setConsensusMemoryManager(consensusMemoryManager); // pipe memory manager MemoryManager pipeMemoryManager = - globalMemoryManager.createMemoryManager("Pipe", pipeMemorySize); + globalMemoryManager.getOrCreateMemoryManager("Pipe", pipeMemorySize); conf.setPipeMemoryManager(pipeMemoryManager); LOGGER.info( @@ -2257,7 +2257,7 @@ private void initMemoryAllocate(TrimProperties properties) { String offHeapMemoryStr = System.getProperty("OFF_HEAP_MEMORY"); MemoryManager offHeapMemoryManager = - globalMemoryManager.createMemoryManager( + globalMemoryManager.gerOrCreateMemoryManager( "OffHeap", MemUtils.strToBytesCnt(offHeapMemoryStr), false); conf.setOffHeapMemoryManager(offHeapMemoryManager); @@ -2270,7 +2270,8 @@ private void initMemoryAllocate(TrimProperties properties) { (offHeapMemoryManager.getTotalMemorySizeInBytes() * conf.getMaxDirectBufferOffHeapMemorySizeProportion()); MemoryManager directBufferMemoryManager = - offHeapMemoryManager.createMemoryManager("DirectBuffer", totalDirectBufferMemorySizeLimit); + offHeapMemoryManager.getOrCreateMemoryManager( + "DirectBuffer", totalDirectBufferMemorySizeLimit); conf.setDirectBufferMemoryManager(directBufferMemoryManager); } @@ -2330,32 +2331,34 @@ private void initStorageEngineAllocate( } } MemoryManager writeMemoryManager = - storageEngineMemoryManager.createMemoryManager("Write", writeMemorySize); + storageEngineMemoryManager.getOrCreateMemoryManager("Write", writeMemorySize); conf.setWriteMemoryManager(writeMemoryManager); MemoryManager compactionMemoryManager = - storageEngineMemoryManager.createMemoryManager("Compaction", compactionMemorySize); + storageEngineMemoryManager.getOrCreateMemoryManager("Compaction", compactionMemorySize); conf.setCompactionMemoryManager(compactionMemoryManager); MemoryManager memtableMemoryManager = - writeMemoryManager.createMemoryManager("Memtable", memtableMemorySize); + writeMemoryManager.getOrCreateMemoryManager("Memtable", memtableMemorySize); conf.setMemtableMemoryManager(memtableMemoryManager); MemoryManager timePartitionMemoryManager = - writeMemoryManager.createMemoryManager("TimePartitionInfo", timePartitionInfoMemorySize); + writeMemoryManager.getOrCreateMemoryManager( + "TimePartitionInfo", timePartitionInfoMemorySize); conf.setTimePartitionInfoMemoryManager(timePartitionMemoryManager); long devicePathCacheMemorySize = (long) (memtableMemorySize * conf.getDevicePathCacheProportion()); MemoryManager devicePathCacheMemoryManager = - memtableMemoryManager.createMemoryManager("DevicePathCache", devicePathCacheMemorySize); + memtableMemoryManager.getOrCreateMemoryManager( + "DevicePathCache", devicePathCacheMemorySize); conf.setDevicePathCacheMemoryManager(devicePathCacheMemoryManager); // TODO @spricoder check why this memory calculate by storage engine memory long bufferedArraysMemorySize = (long) (storageMemoryTotal * conf.getBufferedArraysMemoryProportion()); MemoryManager bufferedArraysMemoryManager = - memtableMemoryManager.createMemoryManager("BufferedArray", bufferedArraysMemorySize); + memtableMemoryManager.getOrCreateMemoryManager("BufferedArray", bufferedArraysMemorySize); conf.setBufferedArraysMemoryManager(bufferedArraysMemoryManager); long walBufferQueueMemorySize = (long) (memtableMemorySize * conf.getWalBufferQueueProportion()); MemoryManager walBufferQueueMemoryManager = - memtableMemoryManager.createMemoryManager("WalBufferQueue", walBufferQueueMemorySize); + memtableMemoryManager.getOrCreateMemoryManager("WalBufferQueue", walBufferQueueMemorySize); conf.setWalBufferQueueManager(walBufferQueueMemoryManager); } @@ -2388,7 +2391,7 @@ private void initSchemaMemoryAllocate( } MemoryManager schemaRegionMemoryManager = - schemaEngineMemoryManager.createMemoryManager( + schemaEngineMemoryManager.getOrCreateMemoryManager( "SchemaRegion", schemaMemoryTotal * schemaMemoryProportion[0] / proportionSum); conf.setSchemaRegionMemoryManager(schemaRegionMemoryManager); LOGGER.info( @@ -2396,7 +2399,7 @@ private void initSchemaMemoryAllocate( conf.getSchemaRegionMemoryManager().getTotalMemorySizeInBytes()); MemoryManager schemaCacheMemoryManager = - schemaEngineMemoryManager.createMemoryManager( + schemaEngineMemoryManager.getOrCreateMemoryManager( "SchemaCache", schemaMemoryTotal * schemaMemoryProportion[1] / proportionSum); conf.setSchemaCacheMemoryManager(schemaCacheMemoryManager); LOGGER.info( @@ -2404,7 +2407,7 @@ private void initSchemaMemoryAllocate( conf.getSchemaCacheMemoryManager().getTotalMemorySizeInBytes()); MemoryManager partitionCacheMemoryManager = - schemaEngineMemoryManager.createMemoryManager( + schemaEngineMemoryManager.getOrCreateMemoryManager( "PartitionCache", schemaMemoryTotal * schemaMemoryProportion[2] / proportionSum); conf.setPartitionCacheMemoryManager(partitionCacheMemoryManager); LOGGER.info( @@ -2482,33 +2485,33 @@ private void initQueryEngineMemoryAllocate( conf.setMaxBytesPerFragmentInstance(dataExchangeMemorySize / conf.getQueryThreadCount()); MemoryManager bloomFilterCacheMemoryManager = - queryEngineMemoryManager.createMemoryManager( + queryEngineMemoryManager.getOrCreateMemoryManager( "BloomFilterCache", bloomFilterCacheMemorySize); conf.setBloomFilterCacheMemoryManager(bloomFilterCacheMemoryManager); MemoryManager chunkCacheMemoryManager = - queryEngineMemoryManager.createMemoryManager("ChunkCache", chunkCacheMemorySize); + queryEngineMemoryManager.getOrCreateMemoryManager("ChunkCache", chunkCacheMemorySize); conf.setChunkCacheMemoryManager(chunkCacheMemoryManager); MemoryManager timeSeriesMetaDataCacheMemoryManager = - queryEngineMemoryManager.createMemoryManager( + queryEngineMemoryManager.getOrCreateMemoryManager( "TimeSeriesMetaDataCache", timeSeriesMetaDataCacheMemorySize); conf.setTimeSeriesMetaDataCacheMemoryManager(timeSeriesMetaDataCacheMemoryManager); MemoryManager coordinatorMemoryManager = - queryEngineMemoryManager.createMemoryManager("Coordinator", coordinatorMemorySize); + queryEngineMemoryManager.getOrCreateMemoryManager("Coordinator", coordinatorMemorySize); conf.setCoordinatorMemoryManager(coordinatorMemoryManager); MemoryManager operatorsMemoryManager = - queryEngineMemoryManager.createMemoryManager("Operators", operatorsMemorySize); + queryEngineMemoryManager.getOrCreateMemoryManager("Operators", operatorsMemorySize); conf.setOperatorsMemoryManager(operatorsMemoryManager); MemoryManager dataExchangeMemoryManager = - queryEngineMemoryManager.createMemoryManager("DataExchange", dataExchangeMemorySize); + queryEngineMemoryManager.getOrCreateMemoryManager("DataExchange", dataExchangeMemorySize); conf.setDataExchangeMemoryManager(dataExchangeMemoryManager); MemoryManager timeIndexMemoryManager = - queryEngineMemoryManager.createMemoryManager("TimeIndex", timeIndexMemorySize); + queryEngineMemoryManager.getOrCreateMemoryManager("TimeIndex", timeIndexMemorySize); conf.setTimeIndexMemoryManager(timeIndexMemoryManager); } @@ -2967,13 +2970,13 @@ public void reclaimConsensusMemory() { long newSize = storageEngineMemoryManager.getTotalMemorySizeInBytes() + consensusMemoryManager.getTotalMemorySizeInBytes(); - globalMemoryManager.removeChild("StorageEngine"); - storageEngineMemoryManager.clear(); + globalMemoryManager.removeChildMemoryManager("StorageEngine"); + storageEngineMemoryManager.clearAll(); // @Spricoder to find a better way - consensusMemoryManager.resize(0); + consensusMemoryManager.setTotalMemorySizeInBytes(0); // then we need to allocate the memory to storage engine conf.setStorageEngineMemoryManager( - globalMemoryManager.createMemoryManager("StorageEngine", newSize)); + globalMemoryManager.getOrCreateMemoryManager("StorageEngine", newSize)); SystemInfo.getInstance().allocateWriteMemory(); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/resource/memory/PipeMemoryManager.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/resource/memory/PipeMemoryManager.java index fc22b115c33b..7dc0c61b723d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/resource/memory/PipeMemoryManager.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/resource/memory/PipeMemoryManager.java @@ -204,7 +204,7 @@ private PipeMemoryBlock forceAllocate(long sizeInBytes, PipeMemoryBlockType type public synchronized void forceResize(PipeMemoryBlock block, long targetSize) { if (block == null || block.isReleased()) { - LOGGER.warn("forceResize: cannot resize a null or released memory block"); + LOGGER.warn("forceResize: cannot setTotalMemorySizeInBytes a null or released memory block"); return; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/memory/GlobalMemoryMetrics.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/memory/GlobalMemoryMetrics.java index 9956d1e77044..6babadc565dc 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/memory/GlobalMemoryMetrics.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/memory/GlobalMemoryMetrics.java @@ -23,7 +23,6 @@ import org.apache.iotdb.commons.service.metric.enums.Tag; import org.apache.iotdb.db.conf.IoTDBConfig; import org.apache.iotdb.db.conf.IoTDBDescriptor; -import org.apache.iotdb.db.storageengine.rescon.memory.SystemInfo; import org.apache.iotdb.metrics.AbstractMetricService; import org.apache.iotdb.metrics.metricsets.IMetricSet; import org.apache.iotdb.metrics.utils.MetricLevel; @@ -34,7 +33,6 @@ public class GlobalMemoryMetrics implements IMetricSet { private static final IoTDBConfig config = IoTDBDescriptor.getInstance().getConfig(); - private static final SystemInfo systemInfo = SystemInfo.getInstance(); private static final String TOTAL = "Total"; public static final String ON_HEAP = "OnHeap"; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/memory/StorageEngineMemoryMetrics.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/memory/StorageEngineMemoryMetrics.java index 486db64c1ab3..ba7f6265d6c6 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/memory/StorageEngineMemoryMetrics.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/memory/StorageEngineMemoryMetrics.java @@ -35,7 +35,7 @@ public class StorageEngineMemoryMetrics implements IMetricSet { private static final String STORAGE_ENGINE = "StorageEngine"; private static final String STORAGE_ENGINE_WRITE = "StorageEngine-Write"; private static final String STORAGE_ENGINE_WRITE_MEMTABLE = "StorageEngine-Write-Memtable"; - private static final String STORAGE_ENGINE_WRITE_MEMTABLE_CACHE = + private static final String STORAGE_ENGINE_WRITE_MEMTABLE_DEVICE_PATH_CACHE = "StorageEngine-Write-Memtable-DevicePathCache"; private static final String STORAGE_ENGINE_WRITE_MEMTABLE_BUFFERED_ARRAYS = "StorageEngine-Write-Memtable-BufferedArrays"; @@ -113,7 +113,7 @@ public void bindTo(AbstractMetricService metricService) { Metric.MEMORY_THRESHOLD_SIZE.toString(), MetricLevel.NORMAL, Tag.NAME.toString(), - STORAGE_ENGINE_WRITE_MEMTABLE_CACHE, + STORAGE_ENGINE_WRITE_MEMTABLE_DEVICE_PATH_CACHE, Tag.TYPE.toString(), GlobalMemoryMetrics.ON_HEAP, Tag.LEVEL.toString(), @@ -179,7 +179,7 @@ public void unbindFrom(AbstractMetricService metricService) { Tag.LEVEL.toString(), GlobalMemoryMetrics.LEVELS[3])); Arrays.asList( - STORAGE_ENGINE_WRITE_MEMTABLE_CACHE, + STORAGE_ENGINE_WRITE_MEMTABLE_DEVICE_PATH_CACHE, STORAGE_ENGINE_WRITE_MEMTABLE_BUFFERED_ARRAYS, STORAGE_ENGINE_WRITE_MEMTABLE_WAL_BUFFER_QUEUE) .forEach( diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileDataCacheMemoryBlock.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileDataCacheMemoryBlock.java index c581ae768f4b..64f588af001b 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileDataCacheMemoryBlock.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileDataCacheMemoryBlock.java @@ -74,7 +74,7 @@ public synchronized void reduceMemoryUsage(long memoryInBytes) { @Override public synchronized void forceResize(long newSizeInBytes) { throw new UnsupportedOperationException( - "resize is not supported for LoadTsFileDataCacheMemoryBlock"); + "setTotalMemorySizeInBytes is not supported for LoadTsFileDataCacheMemoryBlock"); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManager.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManager.java index 7a5fc392d622..095c24a8cc77 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManager.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManager.java @@ -117,7 +117,7 @@ synchronized void forceResize(LoadTsFileAnalyzeSchemaMemoryBlock memoryBlock, lo if (memoryBlock.getMemoryUsageInBytes() > newSizeInBytes) { LOGGER.error( - "Load: Failed to resize memory block {} to {} bytes, current memory usage {} bytes", + "Load: Failed to setTotalMemorySizeInBytes memory block {} to {} bytes, current memory usage {} bytes", memoryBlock, newSizeInBytes, memoryBlock.getMemoryUsageInBytes()); diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/cache/TableDeviceSchemaCacheTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/cache/TableDeviceSchemaCacheTest.java index 70e4fa30ed25..ce27bd9f40ac 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/cache/TableDeviceSchemaCacheTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/cache/TableDeviceSchemaCacheTest.java @@ -159,9 +159,9 @@ public static void clearEnvironment() { private static void changeSchemaCacheMemorySize(long size) { MemoryManager memoryManager = config.getSchemaEngineMemoryManager(); MemoryManager schemaCacheMemoryManager = config.getSchemaCacheMemoryManager(); - schemaCacheMemoryManager.clear(); - memoryManager.removeChild("schemaCache"); - schemaCacheMemoryManager = memoryManager.createMemoryManager("schemaCache", size); + schemaCacheMemoryManager.clearAll(); + memoryManager.removeChildMemoryManager("schemaCache"); + schemaCacheMemoryManager = memoryManager.getOrCreateMemoryManager("schemaCache", size); config.setSchemaCacheMemoryManager(schemaCacheMemoryManager); } diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/IMemoryBlock.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/IMemoryBlock.java index 642580d847bb..059bcabe50cc 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/IMemoryBlock.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/IMemoryBlock.java @@ -35,15 +35,15 @@ public abstract class IMemoryBlock implements AutoCloseable { /** The type of this memory block */ protected MemoryBlockType memoryBlockType; + /** The flag that indicates whether this memory block is released */ + protected volatile boolean isReleased = false; + /** The maximum memory size in byte of this memory block */ protected long maxMemorySizeInByte = 0; /** The memory usage in byte of this memory block */ protected final AtomicLong memoryUsageInBytes = new AtomicLong(0); - /** The flag that indicates whether this memory block is released */ - protected volatile boolean isReleased = false; - /** Try to record memory managed by this memory block */ public abstract void recordMemory(final long size); diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryBlock.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryBlock.java index 2fbf02bec9b9..1d0d856debf4 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryBlock.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryBlock.java @@ -56,14 +56,14 @@ public String toString() { return "IoTDBMemoryBlock{" + "name=" + name + + ", isReleased=" + + isReleased + ", memoryBlockType=" + memoryBlockType + ", maxMemorySizeInByte=" + maxMemorySizeInByte + ", memoryUsageInBytes=" + memoryUsageInBytes - + ", isReleased=" - + isReleased + '}'; } diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryBlockType.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryBlockType.java index 38e78659b1b9..50d22eee50da 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryBlockType.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryBlockType.java @@ -21,6 +21,8 @@ public enum MemoryBlockType { NONE, + // function related memory FUNCTION, + // performance related memory PERFORMANCE, } diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryManager.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryManager.java index 4f56e8e71778..0b5a6f2a5e79 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryManager.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/memory/MemoryManager.java @@ -31,35 +31,34 @@ public class MemoryManager { private static final Logger LOGGER = LoggerFactory.getLogger(MemoryManager.class); - // TODO @spricoder: make it configurable - /** Whether memory management is enabled */ - private final boolean enable; - - /** Max retry times for memory allocation */ + /** The max retry times for memory allocation */ private static final int MEMORY_ALLOCATE_MAX_RETRIES = 3; - /** Retry interval for memory allocation */ + /** The retry interval for memory allocation */ private static final long MEMORY_ALLOCATE_RETRY_INTERVAL_IN_MS = 1000; - /** Min memory size to allocate */ + /** The min memory size to allocate */ private static final long MEMORY_ALLOCATE_MIN_SIZE_IN_BYTES = 32; - /** Name of memory manager */ + /** The name of memory manager */ private final String name; - /** Total memory size in byte of memory manager */ + /** Whether memory management is enabled */ + private final boolean enable; + + /** The total memory size in byte of memory manager */ private long totalMemorySizeInBytes = 0L; - /** Allocated memory size to allocate */ + /** The allocated memory size */ private long allocatedMemorySizeInBytes = 0L; - /** Parent memory manager, used to apply for memory */ + /** The parent memory manager */ private final MemoryManager parentMemoryManager; - /** Child memory manager, used to statistic memory */ - private final Map childrens = new ConcurrentHashMap<>(); + /** The child memory manager */ + private final Map children = new ConcurrentHashMap<>(); - /** Allocated memory blocks of this memory manager */ + /** The allocated memory blocks of this memory manager */ private final Set allocatedMemoryBlocks = new HashSet<>(); private MemoryManager( @@ -78,29 +77,16 @@ private MemoryManager( this.enable = enable; } - public MemoryManager createMemoryManager( - String name, long totalMemorySizeInBytes, boolean enable) { - MemoryManager result = new MemoryManager(name, this, totalMemorySizeInBytes, enable); - return childrens.compute( - name, - (managerName, manager) -> { - if (manager != null) { - LOGGER.warn( - "createMemoryManager failed: memory manager {} already exists, it's size is {}", - managerName, - manager.getTotalMemorySizeInBytes()); - return manager; - } else { - return result; - } - }); - } - - public MemoryManager createMemoryManager(String name, long totalMemorySizeInBytes) { - return createMemoryManager(name, totalMemorySizeInBytes, false); - } + // region memory block management - /** Try to force allocate memory block with specified size in bytes. */ + /** + * Try to force allocate memory block with specified size in bytes + * + * @param name the name of memory block + * @param sizeInBytes the size in bytes of memory block try to allocate + * @param type the type of memory block + * @return the memory block if success, otherwise throw MemoryException + */ public MemoryBlock forceAllocate(String name, long sizeInBytes, MemoryBlockType type) { if (!enable) { return new MemoryBlock(name, this, sizeInBytes, type); @@ -130,7 +116,14 @@ public MemoryBlock forceAllocate(String name, long sizeInBytes, MemoryBlockType sizeInBytes)); } - /** Try to force allocate memory block with specified size in bytes when memory is sufficient. */ + /** + * Try to force allocate memory block with specified size in bytes when memory is sufficient. + * + * @param name the name of memory block + * @param sizeInBytes the size in bytes of memory block try to allocate + * @param usedThreshold the used threshold of allocatedMemorySizeInBytes / totalMemorySizeInBytes + * @return the memory block if success, otherwise null + */ public synchronized MemoryBlock forceAllocateIfSufficient( String name, long sizeInBytes, float usedThreshold) { if (usedThreshold < 0.0f || usedThreshold > 1.0f) { @@ -157,7 +150,15 @@ public synchronized MemoryBlock forceAllocateIfSufficient( return null; } - /** Try to allocate memory block with customAllocateStrategy */ + /** + * Try to allocate memory block with customAllocateStrategy + * + * @param name the name of memory block + * @param sizeInBytes the size in bytes of memory block try to allocate + * @param customAllocateStrategy the custom allocate strategy when memory is insufficient + * @param type the type of memory block + * @return the memory block if success, otherwise null + */ public synchronized MemoryBlock tryAllocate( String name, long sizeInBytes, @@ -174,7 +175,7 @@ public synchronized MemoryBlock tryAllocate( long sizeToAllocateInBytes = sizeInBytes; while (sizeToAllocateInBytes > MEMORY_ALLOCATE_MIN_SIZE_IN_BYTES) { if (totalMemorySizeInBytes - allocatedMemorySizeInBytes >= sizeToAllocateInBytes) { - LOGGER.info( + LOGGER.debug( "tryAllocate: allocated memory, " + "total memory size {} bytes, used memory size {} bytes, " + "original requested memory size {} bytes, " @@ -203,7 +204,14 @@ public synchronized MemoryBlock tryAllocate( return registerMemoryBlock(name, 0, type); } - /** Try to register memory block with specified size in bytes. */ + /** + * Try to register memory block with specified size in bytes + * + * @param name the name of memory block + * @param sizeInBytes the size in bytes of memory block + * @param type + * @return the memory block + */ private MemoryBlock registerMemoryBlock(String name, long sizeInBytes, MemoryBlockType type) { allocatedMemorySizeInBytes += sizeInBytes; final MemoryBlock memoryBlock = new MemoryBlock(name, this, sizeInBytes, type); @@ -211,7 +219,11 @@ private MemoryBlock registerMemoryBlock(String name, long sizeInBytes, MemoryBlo return memoryBlock; } - /** Release memory block. */ + /** + * Release memory block and notify all waiting threads + * + * @param block the memory block to release + */ public synchronized void release(IMemoryBlock block) { if (!enable || block == null || block.isReleased()) { return; @@ -220,6 +232,11 @@ public synchronized void release(IMemoryBlock block) { this.notifyAll(); } + /** + * Release memory block without notify + * + * @param block the memory block to release + */ public synchronized void releaseWithOutNotify(IMemoryBlock block) { if (!enable || block == null || block.isReleased()) { return; @@ -230,13 +247,72 @@ public synchronized void releaseWithOutNotify(IMemoryBlock block) { allocatedMemoryBlocks.remove(block); } + // endregion + + // region memory manager management + + /** + * Try to create a new memory manager with specified name and total memory size in bytes, then put + * it into children map. NOTICE: if there are same name memory manager, it will return the + * existing one. + * + * @param name the name of memory manager + * @param totalMemorySizeInBytes the total memory size in bytes of memory manager + * @param enable whether memory management is enabled + * @return the memory manager + */ + public MemoryManager gerOrCreateMemoryManager( + String name, long totalMemorySizeInBytes, boolean enable) { + MemoryManager result = new MemoryManager(name, this, totalMemorySizeInBytes, enable); + return children.compute( + name, + (managerName, manager) -> { + if (manager != null) { + LOGGER.warn( + "gerOrCreateMemoryManager failed: memory manager {} already exists, it's size is {}, enable is {}", + managerName, + manager.getTotalMemorySizeInBytes(), + manager.isEnable()); + return manager; + } else { + return result; + } + }); + } + + /** + * Try to create a new memory manager with specified name and total memory size in bytes, then put + * it into children map. NOTICE: if there are same name memory manager, it will return the + * existing one. + * + * @param name the name of memory manager + * @param totalMemorySizeInBytes the total memory size in bytes of memory manager + * @return the memory manager + */ + public MemoryManager getOrCreateMemoryManager(String name, long totalMemorySizeInBytes) { + return gerOrCreateMemoryManager(name, totalMemorySizeInBytes, false); + } + + /** + * Get the memory manager with specified names in levels + * + * @param names the names of memory manager in levels + * @return the memory manager if find it, otherwise null + */ public MemoryManager getMemoryManager(String... names) { return getMemoryManager(0, names); } - public MemoryManager getMemoryManager(int index, String... names) { + /** + * Get the memory manager with specified names in levels + * + * @param index the index of names + * @param names the names of memory manager in levels + * @return the memory manager if find it, otherwise null + */ + private MemoryManager getMemoryManager(int index, String... names) { if (index >= names.length) return null; - MemoryManager memoryManager = childrens.get(names[index]); + MemoryManager memoryManager = children.get(names[index]); if (memoryManager != null) { return getMemoryManager(index + 1, names); } else { @@ -244,47 +320,73 @@ public MemoryManager getMemoryManager(int index, String... names) { } } - public long getFreeMemorySizeInBytes() { - return totalMemorySizeInBytes - allocatedMemorySizeInBytes; + /** + * Remove the child memory manager with specified name + * + * @param memoryManagerName the name of memory manager + */ + public void removeChildMemoryManager(String memoryManagerName) { + children.remove(memoryManagerName); } - public long getUsedMemorySizeInBytes() { - long memorySize = - allocatedMemoryBlocks.stream().mapToLong(MemoryBlock::getMemoryUsageInBytes).sum(); - for (MemoryManager child : childrens.values()) { - memorySize += child.getUsedMemorySizeInBytes(); + /** Clear all memory blocks and child memory managers */ + public void clearAll() { + for (MemoryManager child : children.values()) { + child.clearAll(); } - return memorySize; + children.clear(); + for (MemoryBlock block : allocatedMemoryBlocks) { + releaseWithOutNotify(block); + } + allocatedMemoryBlocks.clear(); + parentMemoryManager.removeChildMemoryManager(name); } - public long getAllocatedMemorySizeInBytes() { - return allocatedMemorySizeInBytes; + // endregion + + // region attribute related + + public String getName() { + return name; + } + + public boolean isEnable() { + return enable; } + /** Get total memory size in bytes of memory manager */ public long getTotalMemorySizeInBytes() { return totalMemorySizeInBytes; } - public void resize(long totalMemorySizeInBytes) { + public void setTotalMemorySizeInBytes(long totalMemorySizeInBytes) { this.totalMemorySizeInBytes = totalMemorySizeInBytes; } - public void removeChild(String name) { - childrens.remove(name); + /** Get available memory size in bytes of memory manager */ + public long getAvailableMemorySizeInBytes() { + return totalMemorySizeInBytes - allocatedMemorySizeInBytes; } - public void clear() { - for (MemoryManager child : childrens.values()) { - child.clear(); - } - childrens.clear(); - for (MemoryBlock block : allocatedMemoryBlocks) { - releaseWithOutNotify(block); + /** Get allocated memory size in bytes of memory manager */ + public long getAllocatedMemorySizeInBytes() { + return allocatedMemorySizeInBytes; + } + + /** Get actual used memory size in bytes of memory manager */ + public long getUsedMemorySizeInBytes() { + long memorySize = + allocatedMemoryBlocks.stream().mapToLong(MemoryBlock::getMemoryUsageInBytes).sum(); + for (MemoryManager child : children.values()) { + memorySize += child.getUsedMemorySizeInBytes(); } - allocatedMemoryBlocks.clear(); - parentMemoryManager.removeChild(name); + return memorySize; } + // endregion + + // region global memory manager + public static MemoryManager global() { return MemoryManagerHolder.GLOBAL; } @@ -297,12 +399,15 @@ private static class MemoryManagerHolder { private MemoryManagerHolder() {} } + // endregion + @Override public String toString() { return "MemoryManager{" - + "name='" + + "name=" + name - + '\'' + + ", enable=" + + enable + ", totalMemorySizeInBytes=" + totalMemorySizeInBytes + ", allocatedMemorySizeInBytes="