Port Sponge's heap dump command feature to Paper

To dump the server heap, run the following command:
`/paper heap`

This is added with the intent that it is useful for administrators and
developers to more easily identify and resolve memory leaks. Both by examining
these dumps themselves and by more easily allowing them to send them to
knowledgable parties.

This is a nearly line-for-line port of the same Sponge feature. So all
credit for the idea and implementation belongs to the that team.

Specifically the following commits:
be08be04b0
5e10a1b795
This commit is contained in:
Zach Brown 2017-07-15 18:59:18 -05:00
parent 9a536c5a7b
commit 5938592845
No known key found for this signature in database
GPG Key ID: CC9DA35FC5450B76
4 changed files with 83 additions and 37 deletions

View File

@ -1,4 +1,4 @@
From df3579e7a0ea6ad85593e8632946767660f44554 Mon Sep 17 00:00:00 2001 From fd7aa7456ea06e3fc65cc8ad065d2d4d4ed690ab Mon Sep 17 00:00:00 2001
From: Zach Brown <zach.brown@destroystokyo.com> From: Zach Brown <zach.brown@destroystokyo.com>
Date: Mon, 29 Feb 2016 21:02:09 -0600 Date: Mon, 29 Feb 2016 21:02:09 -0600
Subject: [PATCH] Paper config files Subject: [PATCH] Paper config files
@ -6,10 +6,10 @@ Subject: [PATCH] Paper config files
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
new file mode 100644 new file mode 100644
index 000000000..2096d3f97 index 000000000..cd67ab2bb
--- /dev/null --- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java +++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -0,0 +1,49 @@ @@ -0,0 +1,72 @@
+package com.destroystokyo.paper; +package com.destroystokyo.paper;
+ +
+import net.minecraft.server.MinecraftServer; +import net.minecraft.server.MinecraftServer;
@ -17,15 +17,18 @@ index 000000000..2096d3f97
+import org.bukkit.ChatColor; +import org.bukkit.ChatColor;
+import org.bukkit.command.Command; +import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender; +import org.bukkit.command.CommandSender;
+import org.bukkit.craftbukkit.CraftServer;
+ +
+import java.io.File; +import java.io.File;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+ +
+public class PaperCommand extends Command { +public class PaperCommand extends Command {
+ +
+ public PaperCommand(String name) { + public PaperCommand(String name) {
+ super(name); + super(name);
+ this.description = "Paper related commands"; + this.description = "Paper related commands";
+ this.usageMessage = "/paper [reload | version]"; + this.usageMessage = "/paper [heap | reload | version]";
+ this.setPermission("bukkit.command.paper"); + this.setPermission("bukkit.command.paper");
+ } + }
+ +
@ -38,26 +41,46 @@ index 000000000..2096d3f97
+ return false; + return false;
+ } + }
+ +
+ if (args[0].equals("reload")) { + switch (args[0]) {
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues."); + case "heap":
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server."); + dumpHeap(sender);
+ + break;
+ MinecraftServer console = MinecraftServer.getServer(); + case "reload":
+ com.destroystokyo.paper.PaperConfig.init((File) console.options.valueOf("paper-settings")); + doReload(sender);
+ for (WorldServer world : console.worlds) { + break;
+ world.paperConfig.init(); + case "ver":
+ } + case "version":
+ console.server.reloadCount++; + org.bukkit.Bukkit.getServer().getCommandMap().getCommand("version").execute(sender, commandLabel, new String[0]);
+ + break;
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Paper config reload complete."); + default:
+ } + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
+ + return false;
+ if (args[0].equals("version")) {
+ org.bukkit.Bukkit.getServer().getCommandMap().getCommand("version").execute(sender, commandLabel, new String[0]);
+ } + }
+ +
+ return true; + return true;
+ } + }
+
+ private void dumpHeap(CommandSender sender) {
+ File file = new File(new File(new File("."), "dumps"),
+ "heap-dump-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + "-server.bin");
+ Command.broadcastCommandMessage(sender, ChatColor.YELLOW + "Writing JVM heap data to " + file);
+ CraftServer.dumpHeap(file);
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Heap dump complete");
+ }
+
+ private void doReload(CommandSender sender) {
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues.");
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server.");
+
+ MinecraftServer console = MinecraftServer.getServer();
+ com.destroystokyo.paper.PaperConfig.init((File) console.options.valueOf("paper-settings"));
+ for (WorldServer world : console.worlds) {
+ world.paperConfig.init();
+ }
+ console.server.reloadCount++;
+
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Paper config reload complete.");
+ }
+} +}
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
new file mode 100644 new file mode 100644
@ -347,7 +370,7 @@ index f5d387511..fd204ad7a 100644
this.world = new CraftWorld((WorldServer) this, gen, env); this.world = new CraftWorld((WorldServer) this, gen, env);
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 67ee8c55e..51981c386 100644 index 67ee8c55e..ad075615a 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -696,6 +696,7 @@ public final class CraftServer implements Server { @@ -696,6 +696,7 @@ public final class CraftServer implements Server {
@ -374,6 +397,30 @@ index 67ee8c55e..51981c386 100644
overrideAllCommandBlockCommands = commandsConfiguration.getStringList("command-block-overrides").contains("*"); overrideAllCommandBlockCommands = commandsConfiguration.getStringList("command-block-overrides").contains("*");
int pollCount = 0; int pollCount = 0;
@@ -1771,4 +1774,23 @@ public final class CraftServer implements Server {
{
return spigot;
}
+
+ // Paper start
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public static void dumpHeap(File file) {
+ try {
+ if (file.getParentFile() != null) {
+ file.getParentFile().mkdirs();
+ }
+
+ Class clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
+ javax.management.MBeanServer server = java.lang.management.ManagementFactory.getPlatformMBeanServer();
+ Object hotspotMBean = java.lang.management.ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", clazz);
+ java.lang.reflect.Method m = clazz.getMethod("dumpHeap", String.class, boolean.class);
+ m.invoke(hotspotMBean, file.getPath(), true);
+ } catch (Throwable t) {
+ Bukkit.getLogger().severe("Could not write heap to " + file);
+ }
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
index a151451d5..0c5862a3f 100644 index a151451d5..0c5862a3f 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java --- a/src/main/java/org/bukkit/craftbukkit/Main.java
@ -435,5 +482,5 @@ index 01e73eb89..0b66f5e35 100644
config.addDefault( "world-settings.default." + path, def ); config.addDefault( "world-settings.default." + path, def );
return config.getString( "world-settings." + worldName + "." + path, config.getString( "world-settings.default." + path ) ); return config.getString( "world-settings." + worldName + "." + path, config.getString( "world-settings.default." + path ) );
-- --
2.13.2 2.13.3.windows.1

View File

@ -1,4 +1,4 @@
From 5c366d6ec121cf3a8a4380fc4a39e3fae3cc443c Mon Sep 17 00:00:00 2001 From b7e59de5e65ebabf3ccf76ef226416d49123fac6 Mon Sep 17 00:00:00 2001
From: William <admin@domnian.com> From: William <admin@domnian.com>
Date: Fri, 18 Mar 2016 03:30:17 -0400 Date: Fri, 18 Mar 2016 03:30:17 -0400
Subject: [PATCH] Allow Reloading of Custom Permissions Subject: [PATCH] Allow Reloading of Custom Permissions
@ -6,15 +6,14 @@ Subject: [PATCH] Allow Reloading of Custom Permissions
https://github.com/PaperMC/Paper/issues/49 https://github.com/PaperMC/Paper/issues/49
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 0f6038972..b8f907038 100644 index cc8af9491..a695355dd 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1830,4 +1830,21 @@ public final class CraftServer implements Server { @@ -1848,5 +1848,20 @@ public final class CraftServer implements Server {
{ Bukkit.getLogger().severe("Could not write heap to " + file);
return spigot; }
} }
+ +
+ // Paper start
+ @Override + @Override
+ public void reloadPermissions() { + public void reloadPermissions() {
+ ((SimplePluginManager) pluginManager).clearPermissions(); + ((SimplePluginManager) pluginManager).clearPermissions();
@ -29,8 +28,8 @@ index 0f6038972..b8f907038 100644
+ }); + });
+ } + }
+ } + }
+ // Paper end // Paper end
} }
-- --
2.13.2 2.13.3.windows.1

View File

@ -1,4 +1,4 @@
From ada39c2911337be94248c5c3bef16570c7374c0f Mon Sep 17 00:00:00 2001 From 4f7b6ddc23c4aae58b7d62977b5adc3bb87cb828 Mon Sep 17 00:00:00 2001
From: willies952002 <admin@domnian.com> From: willies952002 <admin@domnian.com>
Date: Mon, 28 Nov 2016 10:21:52 -0500 Date: Mon, 28 Nov 2016 10:21:52 -0500
Subject: [PATCH] Allow Reloading of Command Aliases Subject: [PATCH] Allow Reloading of Command Aliases
@ -6,10 +6,10 @@ Subject: [PATCH] Allow Reloading of Command Aliases
Reload the aliases stored in commands.yml Reload the aliases stored in commands.yml
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 7c872ce6..ee526e91 100644 index bc1847c0c..1a5730a21 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1857,5 +1857,24 @@ public final class CraftServer implements Server { @@ -1874,5 +1874,24 @@ public final class CraftServer implements Server {
}); });
} }
} }

View File

@ -1,4 +1,4 @@
From 7162c39f12cc2d8229abd388d7c1fcbbf8a0ef5e Mon Sep 17 00:00:00 2001 From 276daad3cb0c9174758e498c8035591708d71c5e Mon Sep 17 00:00:00 2001
From: kashike <kashike@vq.lc> From: kashike <kashike@vq.lc>
Date: Fri, 9 Jun 2017 07:24:34 -0700 Date: Fri, 9 Jun 2017 07:24:34 -0700
Subject: [PATCH] Add configuration option to prevent player names from being Subject: [PATCH] Add configuration option to prevent player names from being
@ -6,7 +6,7 @@ Subject: [PATCH] Add configuration option to prevent player names from being
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index 28917f63..f4b23703 100644 index 28917f63d..f4b237034 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -265,4 +265,9 @@ public class PaperConfig { @@ -265,4 +265,9 @@ public class PaperConfig {
@ -20,10 +20,10 @@ index 28917f63..f4b23703 100644
+ } + }
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index ee526e91..dbb44d63 100644 index 1a5730a21..49a321d5d 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1876,5 +1876,10 @@ public final class CraftServer implements Server { @@ -1893,5 +1893,10 @@ public final class CraftServer implements Server {
commandMap.registerServerAliases(); commandMap.registerServerAliases();
return true; return true;
} }