3
0
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:
dordsor21 2024-09-14 21:07:20 +01:00
Ursprung 818a7ac41f
Commit 9caa905d93
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 1E53E88969FFCF0B
4 geänderte Dateien mit 30 neuen und 9 gelöschten Zeilen

Datei anzeigen

@ -17,6 +17,7 @@ import com.fastasyncworldedit.core.queue.IQueueExtent;
import com.fastasyncworldedit.core.queue.implementation.QueueHandler;
import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks;
import com.fastasyncworldedit.core.util.MathMan;
import com.fastasyncworldedit.core.util.MemUtil;
import com.fastasyncworldedit.core.util.NbtUtils;
import com.fastasyncworldedit.core.util.collection.AdaptedMap;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
@ -430,7 +431,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
}
@Override
@SuppressWarnings("rawtypes")
@SuppressWarnings({"rawtypes", "unchecked"})
public synchronized <T extends Future<T>> T call(IQueueExtent<? extends IChunk> owner, IChunkSet set, Runnable finalizer) {
if (!callLock.isHeldByCurrentThread()) {
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;
CompletableFuture<LevelChunk> nmsChunkFuture = ensureLoaded(nmsWorld, chunkX, chunkZ);
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
if (chunk != null) {
return internalCall(set, finalizer, chunk, nmsWorld);

Datei anzeigen

@ -138,6 +138,7 @@ public class Fawe {
} catch (Throwable ignored) {
}
}, 0);
TaskManager.taskManager().repeatAsync(() -> MemUtil.checkAndSetApproachingLimit(), 1);
TaskManager.taskManager().repeat(timer, 1);
@ -417,11 +418,16 @@ public class Fawe {
final NotificationEmitter ne = (NotificationEmitter) memBean;
ne.addNotificationListener((notification, handback) -> {
LOGGER.info("Notification");
final long heapSize = Runtime.getRuntime().totalMemory();
final long heapMaxSize = Runtime.getRuntime().maxMemory();
if (heapSize < heapMaxSize) {
return;
}
LOGGER.info("NNNNNNNNNNNNNNNNNNNNNNNNNNNN");
LOGGER.info("NNNNNNNNNNNNNNNNNNNNNNNNNNNN");
LOGGER.info("NNNNNNNNNNNNNNNNNNNNNNNNNNNN");
LOGGER.info("JJJJJJJJJJJJJJJJJJJJJJJJJJJJ");
MemUtil.memoryLimitedTask();
}, null, null);

Datei anzeigen

@ -2,9 +2,6 @@ package com.fastasyncworldedit.core.queue;
import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock;
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.function.operation.Operation;
import com.sk89q.worldedit.math.BlockVector2;
@ -157,11 +154,7 @@ public interface IQueueExtent<T extends IChunk> extends Flushable, Trimable, ICh
if (newChunk != null) {
chunk = newChunk;
if (block == null) {
if (SimdSupport.useVectorApi() && filter instanceof VectorizedFilter) {
block = new VectorizedCharFilterBlock(this);
} else {
block = this.createFilterBlock();
}
block = this.createFilterBlock();
}
block.initChunk(chunkX, chunkZ);
chunk.filterBlocks(filter, block, region, full);

Datei anzeigen

@ -9,6 +9,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class MemUtil {
private static final AtomicBoolean memory = new AtomicBoolean(false);
private static final AtomicBoolean slower = new AtomicBoolean(false);
public static boolean isMemoryFree() {
return !memory.get();
@ -28,6 +29,10 @@ public class MemUtil {
return false;
}
public static boolean shouldBeginSlow() {
return slower.get();
}
public static long getUsedBytes() {
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
@ -51,6 +56,13 @@ public class MemUtil {
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> memoryPlentifulTasks = new ConcurrentLinkedQueue<>();