diff --git a/CraftBukkit-Patches/0002-mc-dev-imports.patch b/CraftBukkit-Patches/0002-mc-dev-imports.patch index 46c7a30e6..d610b0f0c 100644 --- a/CraftBukkit-Patches/0002-mc-dev-imports.patch +++ b/CraftBukkit-Patches/0002-mc-dev-imports.patch @@ -1945,6 +1945,87 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + void a(Enchantment enchantment, int i); + } +} +diff --git a/src/main/java/net/minecraft/server/FileIOThread.java b/src/main/java/net/minecraft/server/FileIOThread.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/FileIOThread.java +@@ -0,0 +0,0 @@ ++package net.minecraft.server; ++ ++import com.google.common.collect.Lists; ++import java.util.Collections; ++import java.util.List; ++ ++public class FileIOThread implements Runnable { ++ ++ private static final FileIOThread a = new FileIOThread(); ++ private List b = Collections.synchronizedList(Lists.newArrayList()); ++ private volatile long c; ++ private volatile long d; ++ private volatile boolean e; ++ ++ private FileIOThread() { ++ Thread thread = new Thread(this, "File IO Thread"); ++ ++ thread.setPriority(1); ++ thread.start(); ++ } ++ ++ public static FileIOThread a() { ++ return FileIOThread.a; ++ } ++ ++ public void run() { ++ while (true) { ++ this.c(); ++ } ++ } ++ ++ private void c() { ++ for (int i = 0; i < this.b.size(); ++i) { ++ IAsyncChunkSaver iasyncchunksaver = (IAsyncChunkSaver) this.b.get(i); ++ boolean flag = iasyncchunksaver.c(); ++ ++ if (!flag) { ++ this.b.remove(i--); ++ ++this.d; ++ } ++ ++ try { ++ Thread.sleep(this.e ? 0L : 10L); ++ } catch (InterruptedException interruptedexception) { ++ interruptedexception.printStackTrace(); ++ } ++ } ++ ++ if (this.b.isEmpty()) { ++ try { ++ Thread.sleep(25L); ++ } catch (InterruptedException interruptedexception1) { ++ interruptedexception1.printStackTrace(); ++ } ++ } ++ ++ } ++ ++ public void a(IAsyncChunkSaver iasyncchunksaver) { ++ if (!this.b.contains(iasyncchunksaver)) { ++ ++this.c; ++ this.b.add(iasyncchunksaver); ++ } ++ } ++ ++ public void b() throws InterruptedException { ++ this.e = true; ++ ++ while (this.c != this.d) { ++ Thread.sleep(10L); ++ } ++ ++ this.e = false; ++ } ++} diff --git a/src/main/java/net/minecraft/server/GameProfileBanEntry.java b/src/main/java/net/minecraft/server/GameProfileBanEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 diff --git a/CraftBukkit-Patches/0160-Don-t-sleep-between-chunk-saves.patch b/CraftBukkit-Patches/0160-Don-t-sleep-between-chunk-saves.patch new file mode 100644 index 000000000..45b936038 --- /dev/null +++ b/CraftBukkit-Patches/0160-Don-t-sleep-between-chunk-saves.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Wed, 9 Sep 2015 21:09:58 -0400 +Subject: [PATCH] Don't sleep between chunk saves + +For some unknown reason, Minecraft is sleeping 10ms between every single chunk being saved to disk. +Under high chunk load/unload activity (lots of movement / teleporting), this causes the chunk unload queue +to build up in size. + +This has multiple impacts: +1) Performance of the unload queue itself - The save thread is pretty ineffecient for how it accesses it + By letting the queue get larger, checking and popping work off the queue can get less performant. +2) Performance of chunk loading - As with #1, chunk loads also have to check this queue when loading + chunk data so that it doesn't load stale data if new data is pending write to disk. +3) Memory Usage - The entire chunk has been serialized to NBT, and now sits in this queue. This leads to + elevated memory usage, and then the objects used in the serialization sit around longer than needed, + resulting in promotion to Old Generation instead of dying young. + +If there is work to do, then the thread should be doing its work, and only sleep when it is done. + +diff --git a/src/main/java/net/minecraft/server/FileIOThread.java b/src/main/java/net/minecraft/server/FileIOThread.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/FileIOThread.java ++++ b/src/main/java/net/minecraft/server/FileIOThread.java +@@ -0,0 +0,0 @@ public class FileIOThread implements Runnable { + ++this.d; + } + ++ /* // Spigot start - don't sleep in between chunks so we unload faster. + try { + Thread.sleep(this.e ? 0L : 10L); + } catch (InterruptedException interruptedexception) { + interruptedexception.printStackTrace(); +- } ++ } */ // Spigot end + } + + if (this.b.isEmpty()) { +-- \ No newline at end of file