Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-17 00:20:09 +01:00
It's ugly but it stops OOM
Dieser Commit ist enthalten in:
Ursprung
818a7ac41f
Commit
9caa905d93
@ -17,6 +17,7 @@ import com.fastasyncworldedit.core.queue.IQueueExtent;
|
|||||||
import com.fastasyncworldedit.core.queue.implementation.QueueHandler;
|
import com.fastasyncworldedit.core.queue.implementation.QueueHandler;
|
||||||
import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks;
|
import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks;
|
||||||
import com.fastasyncworldedit.core.util.MathMan;
|
import com.fastasyncworldedit.core.util.MathMan;
|
||||||
|
import com.fastasyncworldedit.core.util.MemUtil;
|
||||||
import com.fastasyncworldedit.core.util.NbtUtils;
|
import com.fastasyncworldedit.core.util.NbtUtils;
|
||||||
import com.fastasyncworldedit.core.util.collection.AdaptedMap;
|
import com.fastasyncworldedit.core.util.collection.AdaptedMap;
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
@ -430,7 +431,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
public synchronized <T extends Future<T>> T call(IQueueExtent<? extends IChunk> owner, IChunkSet set, Runnable finalizer) {
|
public synchronized <T extends Future<T>> T call(IQueueExtent<? extends IChunk> owner, IChunkSet set, Runnable finalizer) {
|
||||||
if (!callLock.isHeldByCurrentThread()) {
|
if (!callLock.isHeldByCurrentThread()) {
|
||||||
throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked.");
|
throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked.");
|
||||||
@ -439,6 +440,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
|||||||
final ServerLevel nmsWorld = serverLevel;
|
final ServerLevel nmsWorld = serverLevel;
|
||||||
CompletableFuture<LevelChunk> nmsChunkFuture = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
CompletableFuture<LevelChunk> nmsChunkFuture = ensureLoaded(nmsWorld, chunkX, chunkZ);
|
||||||
LevelChunk chunk = nmsChunkFuture.getNow(null);
|
LevelChunk chunk = nmsChunkFuture.getNow(null);
|
||||||
|
if (chunk == null && MemUtil.shouldBeginSlow()) {
|
||||||
|
try {
|
||||||
|
chunk = nmsChunkFuture.get(); // "Artificially" slow FAWE down if memory low as performing the
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
LOGGER.error("Could not get chunk at {},{} whilst low memory", chunkX, chunkZ, e);
|
||||||
|
throw new FaweException(
|
||||||
|
TextComponent.of("Could not get chunk at " + chunkX + "," + chunkZ + " whilst low memory: " + e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
// Run immediately if possible
|
// Run immediately if possible
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
return internalCall(set, finalizer, chunk, nmsWorld);
|
return internalCall(set, finalizer, chunk, nmsWorld);
|
||||||
|
@ -138,6 +138,7 @@ public class Fawe {
|
|||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
}
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
|
TaskManager.taskManager().repeatAsync(() -> MemUtil.checkAndSetApproachingLimit(), 1);
|
||||||
|
|
||||||
TaskManager.taskManager().repeat(timer, 1);
|
TaskManager.taskManager().repeat(timer, 1);
|
||||||
|
|
||||||
@ -417,11 +418,16 @@ public class Fawe {
|
|||||||
final NotificationEmitter ne = (NotificationEmitter) memBean;
|
final NotificationEmitter ne = (NotificationEmitter) memBean;
|
||||||
|
|
||||||
ne.addNotificationListener((notification, handback) -> {
|
ne.addNotificationListener((notification, handback) -> {
|
||||||
|
LOGGER.info("Notification");
|
||||||
final long heapSize = Runtime.getRuntime().totalMemory();
|
final long heapSize = Runtime.getRuntime().totalMemory();
|
||||||
final long heapMaxSize = Runtime.getRuntime().maxMemory();
|
final long heapMaxSize = Runtime.getRuntime().maxMemory();
|
||||||
if (heapSize < heapMaxSize) {
|
if (heapSize < heapMaxSize) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
LOGGER.info("NNNNNNNNNNNNNNNNNNNNNNNNNNNN");
|
||||||
|
LOGGER.info("NNNNNNNNNNNNNNNNNNNNNNNNNNNN");
|
||||||
|
LOGGER.info("NNNNNNNNNNNNNNNNNNNNNNNNNNNN");
|
||||||
|
LOGGER.info("JJJJJJJJJJJJJJJJJJJJJJJJJJJJ");
|
||||||
MemUtil.memoryLimitedTask();
|
MemUtil.memoryLimitedTask();
|
||||||
}, null, null);
|
}, null, null);
|
||||||
|
|
||||||
|
@ -2,9 +2,6 @@ package com.fastasyncworldedit.core.queue;
|
|||||||
|
|
||||||
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
|
||||||
import com.fastasyncworldedit.core.extent.processor.IBatchProcessorHolder;
|
import com.fastasyncworldedit.core.extent.processor.IBatchProcessorHolder;
|
||||||
import com.fastasyncworldedit.core.internal.simd.SimdSupport;
|
|
||||||
import com.fastasyncworldedit.core.internal.simd.VectorizedCharFilterBlock;
|
|
||||||
import com.fastasyncworldedit.core.internal.simd.VectorizedFilter;
|
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.function.operation.Operation;
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
@ -157,11 +154,7 @@ public interface IQueueExtent<T extends IChunk> extends Flushable, Trimable, ICh
|
|||||||
if (newChunk != null) {
|
if (newChunk != null) {
|
||||||
chunk = newChunk;
|
chunk = newChunk;
|
||||||
if (block == null) {
|
if (block == null) {
|
||||||
if (SimdSupport.useVectorApi() && filter instanceof VectorizedFilter) {
|
block = this.createFilterBlock();
|
||||||
block = new VectorizedCharFilterBlock(this);
|
|
||||||
} else {
|
|
||||||
block = this.createFilterBlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
block.initChunk(chunkX, chunkZ);
|
block.initChunk(chunkX, chunkZ);
|
||||||
chunk.filterBlocks(filter, block, region, full);
|
chunk.filterBlocks(filter, block, region, full);
|
||||||
|
@ -9,6 +9,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
public class MemUtil {
|
public class MemUtil {
|
||||||
|
|
||||||
private static final AtomicBoolean memory = new AtomicBoolean(false);
|
private static final AtomicBoolean memory = new AtomicBoolean(false);
|
||||||
|
private static final AtomicBoolean slower = new AtomicBoolean(false);
|
||||||
|
|
||||||
public static boolean isMemoryFree() {
|
public static boolean isMemoryFree() {
|
||||||
return !memory.get();
|
return !memory.get();
|
||||||
@ -28,6 +29,10 @@ public class MemUtil {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean shouldBeginSlow() {
|
||||||
|
return slower.get();
|
||||||
|
}
|
||||||
|
|
||||||
public static long getUsedBytes() {
|
public static long getUsedBytes() {
|
||||||
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
||||||
}
|
}
|
||||||
@ -51,6 +56,13 @@ public class MemUtil {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void checkAndSetApproachingLimit() {
|
||||||
|
final long heapFreeSize = Runtime.getRuntime().freeMemory();
|
||||||
|
final long heapMaxSize = Runtime.getRuntime().maxMemory();
|
||||||
|
final int size = (int) ((heapFreeSize * 100) / heapMaxSize);
|
||||||
|
slower.set(size > 80);
|
||||||
|
}
|
||||||
|
|
||||||
private static final Queue<Runnable> memoryLimitedTasks = new ConcurrentLinkedQueue<>();
|
private static final Queue<Runnable> memoryLimitedTasks = new ConcurrentLinkedQueue<>();
|
||||||
private static final Queue<Runnable> memoryPlentifulTasks = new ConcurrentLinkedQueue<>();
|
private static final Queue<Runnable> memoryPlentifulTasks = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren