Mirror von
https://github.com/PaperMC/Paper.git
synchronisiert 2024-12-16 03:20:07 +01:00
prevent crashes on expiring map desync, dont spam logs
Dieser Commit ist enthalten in:
Ursprung
d5da5375a6
Commit
80ee619035
@ -1,4 +1,4 @@
|
|||||||
From 6a439506b07605dd8566c86b672d3ee955715b51 Mon Sep 17 00:00:00 2001
|
From 36d303e9b7046708890efc99f68d8dbab88ce4ac Mon Sep 17 00:00:00 2001
|
||||||
From: Aikar <aikar@aikar.co>
|
From: Aikar <aikar@aikar.co>
|
||||||
Date: Sun, 16 Sep 2018 00:00:16 -0400
|
Date: Sun, 16 Sep 2018 00:00:16 -0400
|
||||||
Subject: [PATCH] Fix major memory leaks in ExpiringMap
|
Subject: [PATCH] Fix major memory leaks in ExpiringMap
|
||||||
@ -11,10 +11,10 @@ not run on every manipulation, and instead to run clean
|
|||||||
once per tick per expiring map.
|
once per tick per expiring map.
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/ExpiringMap.java b/src/main/java/net/minecraft/server/ExpiringMap.java
|
diff --git a/src/main/java/net/minecraft/server/ExpiringMap.java b/src/main/java/net/minecraft/server/ExpiringMap.java
|
||||||
index 4006f5a69c..49021d29ee 100644
|
index 4006f5a69c..08d41e8cf0 100644
|
||||||
--- a/src/main/java/net/minecraft/server/ExpiringMap.java
|
--- a/src/main/java/net/minecraft/server/ExpiringMap.java
|
||||||
+++ b/src/main/java/net/minecraft/server/ExpiringMap.java
|
+++ b/src/main/java/net/minecraft/server/ExpiringMap.java
|
||||||
@@ -6,25 +6,113 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
@@ -6,25 +6,120 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2LongMap.Entry;
|
import it.unimi.dsi.fastutil.longs.Long2LongMap.Entry;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -116,10 +116,17 @@ index 4006f5a69c..49021d29ee 100644
|
|||||||
+ @Override
|
+ @Override
|
||||||
+ public T compute(Long aLong, BiFunction<? super Long, ? super T, ? extends T> biFunction) {
|
+ public T compute(Long aLong, BiFunction<? super Long, ? super T, ? extends T> biFunction) {
|
||||||
+ setAccess(aLong);
|
+ setAccess(aLong);
|
||||||
+ return compute(aLong, biFunction);
|
+ return super.compute(aLong, biFunction);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public synchronized void clear() {
|
||||||
|
+ ttl.clear();
|
||||||
|
+ super.clear();
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ private boolean registered = false;
|
+ private boolean registered = false;
|
||||||
|
+ private boolean hasLeaked = false;
|
||||||
+
|
+
|
||||||
+ // Break clean to its own method to be ticked
|
+ // Break clean to its own method to be ticked
|
||||||
+ synchronized boolean clean() {
|
+ synchronized boolean clean() {
|
||||||
@ -136,16 +143,23 @@ index 4006f5a69c..49021d29ee 100644
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +121,18 @@ public class ExpiringMap<T> extends Long2ObjectOpenHashMap<T> {
|
@@ -33,7 +128,25 @@ public class ExpiringMap<T> extends Long2ObjectOpenHashMap<T> {
|
||||||
objectiterator.remove();
|
objectiterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
-
|
-
|
||||||
+ if (this.ttl.size() != this.size()) {
|
+ int ttlSize = this.ttl.size();
|
||||||
+ MinecraftServer.LOGGER.error("WARNING: ExpiringMap desync - Memory leak risk!");
|
+ int thisSize = this.size();
|
||||||
+ for (Entry<T> entry : this.long2ObjectEntrySet()) {
|
+ if (ttlSize != thisSize) {
|
||||||
+ ttl.putIfAbsent(entry.getLongKey(), now);
|
+ if (!hasLeaked) { // log once
|
||||||
|
+ hasLeaked = true;
|
||||||
|
+ MinecraftServer.LOGGER.warn("WARNING: ExpiringMap desync (" + ttlSize + ":" + thisSize + ")- Memory leak risk! We will recover from this, but this means there is still a bug. Please do not open an issue about this. Mention it in Discord (we don't need everyone reporting the same thing)");
|
||||||
+ }
|
+ }
|
||||||
|
+ try {
|
||||||
|
+ for (Entry<T> entry : this.long2ObjectEntrySet()) {
|
||||||
|
+ ttl.putIfAbsent(entry.getLongKey(), now);
|
||||||
|
+ }
|
||||||
|
+ } catch (Exception e) { } // Ignore any como's
|
||||||
+ }
|
+ }
|
||||||
+ if (isEmpty()) {
|
+ if (isEmpty()) {
|
||||||
+ registered = false;
|
+ registered = false;
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren