Remove toProcessTrackingUnloading

This field is covered by the entity tracker optimisations in Paper,
but currently was not properly maintained - resulting in memory leaks.

Fixes https://github.com/PaperMC/Folia/issues/283
This commit is contained in:
Spottedleaf 2024-08-30 12:57:17 -07:00
parent 11e6f61697
commit d8461e8ec5
2 changed files with 7 additions and 28 deletions

View File

@ -2832,10 +2832,10 @@ index 0000000000000000000000000000000000000000..a1e1782d87403ca8934d37361be7ba66
+} +}
diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..5dc4c8a5b896f519be5414d4a53a71144c225324 index 0000000000000000000000000000000000000000..cd89a11ff94dfbb9c9e259b85f931bd0d160c06e
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java +++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedWorldData.java
@@ -0,0 +1,772 @@ @@ -0,0 +1,751 @@
+package io.papermc.paper.threadedregions; +package io.papermc.paper.threadedregions;
+ +
+import ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet; +import ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet;
@ -2925,9 +2925,6 @@ index 0000000000000000000000000000000000000000..5dc4c8a5b896f519be5414d4a53a7114
+ for (final Entity entity : from.loadedEntities) { + for (final Entity entity : from.loadedEntities) {
+ into.loadedEntities.add(entity); + into.loadedEntities.add(entity);
+ } + }
+ for (final Entity entity : from.toProcessTrackingUnloading) {
+ into.toProcessTrackingUnloading.add(entity);
+ }
+ for (final Iterator<Entity> iterator = from.entityTickList.unsafeIterator(); iterator.hasNext();) { + for (final Iterator<Entity> iterator = from.entityTickList.unsafeIterator(); iterator.hasNext();) {
+ into.entityTickList.add(iterator.next()); + into.entityTickList.add(iterator.next());
+ } + }
@ -3029,11 +3026,6 @@ index 0000000000000000000000000000000000000000..5dc4c8a5b896f519be5414d4a53a7114
+ if (from.loadedEntities.contains(entity)) { + if (from.loadedEntities.contains(entity)) {
+ into.loadedEntities.add(entity); + into.loadedEntities.add(entity);
+ } + }
+ // Note: toProcessTrackingUnloading is not a subset of allEntities, but for the cases where it is not
+ // do not matter as the tracker removal is handled
+ if (from.toProcessTrackingUnloading.contains(entity)) {
+ into.toProcessTrackingUnloading.add(entity);
+ }
+ // Note: navigatingMobs is a subset of allEntities + // Note: navigatingMobs is a subset of allEntities
+ if (entity instanceof Mob mob && from.navigatingMobs.contains(mob)) { + if (entity instanceof Mob mob && from.navigatingMobs.contains(mob)) {
+ into.navigatingMobs.add(mob); + into.navigatingMobs.add(mob);
@ -3178,7 +3170,6 @@ index 0000000000000000000000000000000000000000..5dc4c8a5b896f519be5414d4a53a7114
+ private final NearbyPlayers nearbyPlayers; + private final NearbyPlayers nearbyPlayers;
+ private final ReferenceList<Entity> allEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); + private final ReferenceList<Entity> allEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY);
+ private final ReferenceList<Entity> loadedEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); + private final ReferenceList<Entity> loadedEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY);
+ private final ReferenceList<Entity> toProcessTrackingUnloading = new ReferenceList<>(EMPTY_ENTITY_ARRAY);
+ private final IteratorSafeOrderedReferenceSet<Entity> entityTickList = new IteratorSafeOrderedReferenceSet<>(); + private final IteratorSafeOrderedReferenceSet<Entity> entityTickList = new IteratorSafeOrderedReferenceSet<>();
+ private final IteratorSafeOrderedReferenceSet<Mob> navigatingMobs = new IteratorSafeOrderedReferenceSet<>(); + private final IteratorSafeOrderedReferenceSet<Mob> navigatingMobs = new IteratorSafeOrderedReferenceSet<>();
+ public final ReferenceList<Entity> trackerEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker + public final ReferenceList<Entity> trackerEntities = new ReferenceList<>(EMPTY_ENTITY_ARRAY); // Moonrise - entity tracker
@ -3386,9 +3377,7 @@ index 0000000000000000000000000000000000000000..5dc4c8a5b896f519be5414d4a53a7114
+ } + }
+ +
+ public void addLoadedEntity(final Entity entity) { + public void addLoadedEntity(final Entity entity) {
+ if (this.loadedEntities.add(entity)) { + this.loadedEntities.add(entity);
+ this.toProcessTrackingUnloading.remove(entity);
+ }
+ } + }
+ +
+ public boolean hasLoadedEntity(final Entity entity) { + public boolean hasLoadedEntity(final Entity entity) {
@ -3396,23 +3385,13 @@ index 0000000000000000000000000000000000000000..5dc4c8a5b896f519be5414d4a53a7114
+ } + }
+ +
+ public void removeLoadedEntity(final Entity entity) { + public void removeLoadedEntity(final Entity entity) {
+ if (this.loadedEntities.remove(entity)) { + this.loadedEntities.remove(entity);
+ this.toProcessTrackingUnloading.add(entity);
+ }
+ } + }
+ +
+ public Iterable<Entity> getLoadedEntities() { + public Iterable<Entity> getLoadedEntities() {
+ return this.loadedEntities; + return this.loadedEntities;
+ } + }
+ +
+ public Entity[] takeTrackingUnloads() {
+ final Entity[] ret = Arrays.copyOf(this.toProcessTrackingUnloading.getRawData(), this.toProcessTrackingUnloading.size(), Entity[].class);
+
+ this.toProcessTrackingUnloading.clear();
+
+ return ret;
+ }
+
+ public void addEntityTickingEntity(final Entity entity) { + public void addEntityTickingEntity(final Entity entity) {
+ if (!TickThread.isTickThreadFor(entity)) { + if (!TickThread.isTickThreadFor(entity)) {
+ throw new IllegalArgumentException("Entity " + entity + " is not under this region's control"); + throw new IllegalArgumentException("Entity " + entity + " is not under this region's control");
@ -10327,7 +10306,7 @@ index dd56c8e041116ef3602a9f89c998c8208ab89b51..301d7fa29fce2997a5881b3852896eff
if (waitableArray[0] != null) { if (waitableArray[0] != null) {
//noinspection unchecked //noinspection unchecked
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 1e0a6e5a3c907ab55ee6f2780a7d43bd455f2b7b..7f161864ee6a43de8d37c0e5c9cba9918f2fed89 100644 index 1e0a6e5a3c907ab55ee6f2780a7d43bd455f2b7b..dff1f17a4c164e82ed4f5d9e9f48ee62c671e589 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -138,8 +138,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -138,8 +138,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
@ -10478,7 +10457,7 @@ index 1e0a6e5a3c907ab55ee6f2780a7d43bd455f2b7b..7f161864ee6a43de8d37c0e5c9cba991
- if (playerchunkmap_entitytracker1.entity != entityplayer) { - if (playerchunkmap_entitytracker1.entity != entityplayer) {
- playerchunkmap_entitytracker1.updatePlayer(entityplayer); - playerchunkmap_entitytracker1.updatePlayer(entityplayer);
+ // Folia start - region threading + // Folia start - region threading
+ for (Entity possible : this.level.getCurrentWorldData().getLoadedEntities()) { + for (Entity possible : this.level.getCurrentWorldData().trackerEntities) {
+ if (possible.moonrise$getTrackedEntity() != null) { + if (possible.moonrise$getTrackedEntity() != null) {
+ possible.moonrise$getTrackedEntity().updatePlayer(entityplayer); + possible.moonrise$getTrackedEntity().updatePlayer(entityplayer);
} }

View File

@ -1460,7 +1460,7 @@ index eda5f0d099f9f8621de8ad7808098abf6f5cb544..ac56b02498eb38883ae462be6ef3d15c
this.profiler.popPush("players"); this.profiler.popPush("players");
MinecraftTimings.playerListTimer.startTiming(); // Spigot // Paper MinecraftTimings.playerListTimer.startTiming(); // Spigot // Paper
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 7f161864ee6a43de8d37c0e5c9cba9918f2fed89..31f2f6e841179a2fba2199afa7d6211eb68d3c07 100644 index dff1f17a4c164e82ed4f5d9e9f48ee62c671e589..728454fcfbeddcfe1b0a95e89827f33d7f7838bc 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -392,13 +392,18 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -392,13 +392,18 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider