diff --git a/CraftBukkit-Patches/0002-mc-dev-imports.patch b/CraftBukkit-Patches/0002-mc-dev-imports.patch index 3ef640d786..690cef1ce8 100644 --- a/CraftBukkit-Patches/0002-mc-dev-imports.patch +++ b/CraftBukkit-Patches/0002-mc-dev-imports.patch @@ -1,4 +1,4 @@ -From e3594bfb2e702b31dfb5ed0e2b1c00d58036449c Mon Sep 17 00:00:00 2001 +From 53f6a9f493204f2c521e776e3faff4252b1ba69b Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 1 Dec 2013 15:10:48 +1100 Subject: [PATCH] mc-dev imports @@ -1945,6 +1945,87 @@ index 0000000..9865681 + 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 0000000..198b00f +--- /dev/null ++++ b/src/main/java/net/minecraft/server/FileIOThread.java +@@ -0,0 +1,75 @@ ++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 0000000..27ce9d9 @@ -4930,5 +5011,5 @@ index 0000000..31fc0a9 + } +} -- -2.1.4 +1.9.1 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 0000000000..f8ef8bcb9e --- /dev/null +++ b/CraftBukkit-Patches/0160-Don-t-sleep-between-chunk-saves.patch @@ -0,0 +1,41 @@ +From e2baf643e39f01e43476500f56f49ee1e284a1fb 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 198b00f..c9b3bf4 100644 +--- a/src/main/java/net/minecraft/server/FileIOThread.java ++++ b/src/main/java/net/minecraft/server/FileIOThread.java +@@ -39,11 +39,12 @@ 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()) { +-- +2.1.4 +