diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 7fd8c353..6a2e8330 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1267,6 +1267,7 @@ Fluid chunk terrain bounds transfer Cellular transfer behavior work Native math utils Frame tracking on native side +Fix memory leak in client fluid data chunks # TODO diff --git a/src/main/java/electrosphere/client/fluid/cache/ClientFluidCache.java b/src/main/java/electrosphere/client/fluid/cache/ClientFluidCache.java index 94ba847c..91d3b5de 100644 --- a/src/main/java/electrosphere/client/fluid/cache/ClientFluidCache.java +++ b/src/main/java/electrosphere/client/fluid/cache/ClientFluidCache.java @@ -2,8 +2,8 @@ package electrosphere.client.fluid.cache; import java.util.HashMap; import java.util.LinkedList; -import java.util.List; import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; /** @@ -16,7 +16,12 @@ public class ClientFluidCache { //the map of chunk key -> chunk data Map cacheMap = new HashMap(); //the list of keys in the cache - List cacheList = new LinkedList(); + LinkedList cacheList = new LinkedList(); + + /** + * Lock for the fluid cache to threadsafe + */ + ReentrantLock lock = new ReentrantLock(); /** * Constructor @@ -34,12 +39,21 @@ public class ClientFluidCache { * @param chunkData The chunk data to add at the specified positions */ public void addChunkDataToCache(int worldX, int worldY, int worldZ, FluidChunkData chunkData){ - cacheMap.put(getKey(worldX,worldY,worldZ),chunkData); + lock.lock(); + String key = this.getKey(worldX,worldY,worldZ); + if(cacheMap.containsKey(key)){ + FluidChunkData currentChunk = cacheMap.remove(key); + cacheList.remove(key); + currentChunk.freeBuffers(); + } + cacheMap.put(key,chunkData); + cacheList.add(key); while(cacheList.size() > cacheSize){ - String currentKey = cacheList.remove(0); + String currentKey = cacheList.pop(); FluidChunkData currentChunk = cacheMap.remove(currentKey); currentChunk.freeBuffers(); } + lock.unlock(); } @@ -62,7 +76,10 @@ public class ClientFluidCache { * @return True if the cache contains chunk data at the specified point, false otherwise */ public boolean containsChunkDataAtWorldPoint(int worldX, int worldY, int worldZ){ - return cacheMap.containsKey(getKey(worldX,worldY,worldZ)); + lock.lock(); + boolean rVal = cacheMap.containsKey(getKey(worldX,worldY,worldZ)); + lock.unlock(); + return rVal; } @@ -77,7 +94,10 @@ public class ClientFluidCache { * @return The chunk data if it exists, null otherwise */ public FluidChunkData getSubChunkDataAtPoint(int worldX, int worldY, int worldZ){ - return cacheMap.get(getKey(worldX,worldY,worldZ)); + lock.lock(); + FluidChunkData rVal = cacheMap.get(getKey(worldX,worldY,worldZ)); + lock.unlock(); + return rVal; } } diff --git a/src/main/java/electrosphere/client/fluid/cache/FluidChunkData.java b/src/main/java/electrosphere/client/fluid/cache/FluidChunkData.java index 6328d960..b5ad2801 100644 --- a/src/main/java/electrosphere/client/fluid/cache/FluidChunkData.java +++ b/src/main/java/electrosphere/client/fluid/cache/FluidChunkData.java @@ -5,6 +5,7 @@ import java.nio.ByteOrder; import java.nio.FloatBuffer; import org.joml.Vector3i; +import org.lwjgl.BufferUtils; import electrosphere.server.fluid.manager.ServerFluidChunk; @@ -180,14 +181,18 @@ public class FluidChunkData { * Frees the buffers contained within this chunk */ public void freeBuffers(){ - this.free(); + // this.free(); } /** * Allocates the buffers for this data */ public void allocateBuffs(){ - this.allocate(); + // this.allocate(); + this.bWeights = BufferUtils.createByteBuffer(CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * 4); + this.bVelocityX = BufferUtils.createByteBuffer(CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * 4); + this.bVelocityY = BufferUtils.createByteBuffer(CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * 4); + this.bVelocityZ = BufferUtils.createByteBuffer(CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE * 4); //reorder this.bWeights.order(ByteOrder.LITTLE_ENDIAN); diff --git a/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java b/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java index 21a70edc..bd643692 100644 --- a/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java +++ b/src/main/java/electrosphere/client/fluid/manager/ClientFluidManager.java @@ -34,7 +34,7 @@ public class ClientFluidManager { public static final int INTERPOLATION_RATIO = ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO; //caches chunks from server - static final int CACHE_SIZE = 50; + static final int CACHE_SIZE = 250; //used for caching the macro values ClientFluidCache fluidCache;