No more. memory leak in pregen

This commit is contained in:
Brian Neumann-Fopiano
2026-06-03 19:08:32 -04:00
parent 11efae428f
commit 03f9e233da
3 changed files with 14 additions and 24 deletions
@@ -284,7 +284,6 @@ public class IrisPregenerator {
Mantle mantle = getMantle();
if (mantle != null) {
mantle.trim(0, 0);
mantle.unloadTectonicPlate(0);
}
}
@@ -91,8 +91,6 @@ public class AsyncPregenMethod implements PregeneratorMethod {
private final int maxResidentTectonicPlates;
private final int mantleBackpressureWaitMs;
private final long mantleBackpressureTimeoutMs;
private final long mantleReclaimIntervalMs;
private final AtomicLong lastMantleReclaim = new AtomicLong(0L);
public AsyncPregenMethod(World world, int unusedThreads) {
if (!PaperLib.isPaper()) {
@@ -145,7 +143,6 @@ public class AsyncPregenMethod implements PregeneratorMethod {
this.maxResidentTectonicPlates = pregen.getMaxResidentTectonicPlates();
this.mantleBackpressureWaitMs = pregen.getMantleBackpressureWaitMs();
this.mantleBackpressureTimeoutMs = pregen.getMantleBackpressureTimeoutMs();
this.mantleReclaimIntervalMs = 1_000L;
}
private IrisPaperLikeBackendMode resolvePaperLikeBackendMode(IrisSettings.IrisSettingsPregen pregen) {
@@ -501,31 +498,25 @@ public class AsyncPregenMethod implements PregeneratorMethod {
return;
}
long now = M.ms();
long lastReclaimAt = lastMantleReclaim.get();
if (now - lastReclaimAt >= mantleReclaimIntervalMs && lastMantleReclaim.compareAndSet(lastReclaimAt, now)) {
mantle.trim(0L, 0);
mantle.unloadTectonicPlate(0);
}
if (mantle.getLoadedRegionCount() <= cap) {
int hardCap = cap * 2;
if (mantle.getLoadedRegionCount() <= hardCap) {
return;
}
long waitStart = M.ms();
long lastLog = 0L;
while (mantle.getLoadedRegionCount() > cap) {
while (mantle.getLoadedRegionCount() > hardCap) {
mantle.trim(0L, 0);
int freed = mantle.unloadTectonicPlate(0);
int resident = mantle.getLoadedRegionCount();
if (resident <= cap) {
if (resident <= hardCap) {
break;
}
long elapsed = M.ms() - waitStart;
if (elapsed >= mantleBackpressureTimeoutMs) {
Iris.warn("Pregen mantle backpressure exceeded " + mantleBackpressureTimeoutMs + "ms with " + resident
+ " tectonic plates resident (cap " + cap + "); proceeding to avoid deadlock. "
+ " tectonic plates resident (hard cap " + hardCap + "); proceeding to avoid deadlock. "
+ "Raise pregen.maxResidentTectonicPlates if this persists. " + metricsSnapshot());
return;
}
@@ -533,7 +524,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
long logNow = M.ms();
if (logNow - lastLog >= 5_000L) {
lastLog = logNow;
Iris.warn("Pregen mantle backpressure: " + resident + " tectonic plates resident (cap " + cap
Iris.warn("Pregen mantle backpressure: " + resident + " tectonic plates resident (hard cap " + hardCap
+ "), freed " + freed + " last pass, waited " + elapsed + "ms.");
}
@@ -33,7 +33,6 @@ import java.util.concurrent.atomic.AtomicLong;
public class IrisEngineSVC implements IrisService {
private static final int TRIM_PERIOD = 2_000;
private static final long ACTIVE_PREGEN_IDLE_MILLIS = 500L;
private final AtomicInteger tectonicLimit = new AtomicInteger(30);
private final AtomicInteger tectonicPlates = new AtomicInteger();
private final AtomicInteger queuedTectonicPlates = new AtomicInteger();
@@ -188,7 +187,8 @@ public class IrisEngineSVC implements IrisService {
}
private void add(World world) {
var access = IrisToolbelt.access(world);
if (world == null || worlds.containsKey(world)) return;
PlatformChunkGenerator access = IrisToolbelt.access(world);
if (access == null) return;
worlds.put(world, new Registered(world.getName(), access));
}
@@ -201,6 +201,10 @@ public class IrisEngineSVC implements IrisService {
@Override
protected long loop() {
try {
for (World world : Bukkit.getWorlds()) {
add(world);
}
int queuedPlates = 0;
int totalPlates = 0;
long chunks = 0;
@@ -372,15 +376,11 @@ public class IrisEngineSVC implements IrisService {
return limit;
}
return Math.max(1, Math.min(limit, Math.max(2, limit / 8)));
return Math.max(limit, IrisSettings.get().getPregen().getMaxResidentTectonicPlates());
}
private long activeIdleDuration(Engine engine) {
if (!pregenTargets(engine)) {
return TimeUnit.SECONDS.toMillis(IrisSettings.get().getPerformance().getMantleKeepAlive());
}
return ACTIVE_PREGEN_IDLE_MILLIS;
return TimeUnit.SECONDS.toMillis(IrisSettings.get().getPerformance().getMantleKeepAlive());
}
@Synchronized