I'm working on my hub plugin, which worked previously when it didn't constantly open an inventory for a player, but now that it does constantly keep a menu open, my hub seems to crash after a while. How it works: This menu will always be open while in the hub until you make a selection or are kicked (15 seconds). If you close the menu, it re-opens 1 tick later. Code (Text): public void open(Player player) { new BukkitRunnable() { public void run() { player.openInventory(inventory); // line 59 of Menu class } }.runTaskLater(jHub.getInstance(), 1L); } Here are the errors before it crashes: Code (Text): [23:17:19] [Server thread/WARN]: [jHub] Task #223342 for jHub v1.0 generated an exception java.lang.OutOfMemoryError: GC overhead limit exceeded at net.minecraft.server.v1_7_R4.ContainerChest.<init>(ContainerChest.java:50) ~[paperspigot.jar:git-PaperSpigot-36] at net.minecraft.server.v1_7_R4.EntityPlayer.openContainer(EntityPlayer.java:640) ~[paperspigot.jar:git-PaperSpigot-36] at org.bukkit.craftbukkit.v1_7_R4.entity.CraftHumanEntity.openInventory(CraftHumanEntity.java:193) ~[paperspigot.jar:git-PaperSpigot-36] at me.joeleoli.jhub.menu.Menu$1.run(Menu.java:59) ~[?:?] at org.bukkit.craftbukkit.v1_7_R4.scheduler.CraftTask.run(CraftTask.java:71) ~[paperspigot.jar:git-PaperSpigot-36] at org.bukkit.craftbukkit.v1_7_R4.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:350) [paperspigot.jar:git-PaperSpigot-36] at net.minecraft.server.v1_7_R4.MinecraftServer.v(MinecraftServer.java:696) [paperspigot.jar:git-PaperSpigot-36] at net.minecraft.server.v1_7_R4.DedicatedServer.v(DedicatedServer.java:307) [paperspigot.jar:git-PaperSpigot-36] at net.minecraft.server.v1_7_R4.MinecraftServer.u(MinecraftServer.java:638) [paperspigot.jar:git-PaperSpigot-36] at net.minecraft.server.v1_7_R4.MinecraftServer.run(MinecraftServer.java:544) [paperspigot.jar:git-PaperSpigot-36] at net.minecraft.server.v1_7_R4.ThreadServerApplication.run(SourceFile:628) [paperspigot.jar:git-PaperSpigot-36] [23:17:32] [Server thread/WARN]: [jHub] Task #223352 for jHub v1.0 generated an exception java.lang.OutOfMemoryError: GC overhead limit exceeded [23:18:23] [Server thread/WARN]: [jHub] Task #223356 for jHub v1.0 generated an exception java.lang.OutOfMemoryError: GC overhead limit exceeded [23:19:01] [Snooper Timer/WARN]: Exception in thread "Snooper Timer" [23:19:21] [Spigot Watchdog Thread/ERROR]: The server has stopped responding! [23:19:56] [Snooper Timer/WARN]: java.lang.OutOfMemoryError: GC overhead limit exceeded [23:20:38] [Netty IO #3/WARN]: An exception was thrown by a user handler's exceptionCaught() method while handling the following exception: java.lang.OutOfMemoryError: GC overhead limit exceeded [23:20:48] [Netty IO #2/WARN]: An exception was thrown by a user handler's exceptionCaught() method while handling the following exception: java.lang.OutOfMemoryError: GC overhead limit exceeded [23:21:15] [Netty IO #0/WARN]: An exception was thrown by a user handler's exceptionCaught() method while handling the following exception: java.lang.OutOfMemoryError: GC overhead limit exceeded [23:21:47] [Netty IO #2/WARN]: An exception was thrown by a user handler's exceptionCaught() method while handling the following exception: java.lang.OutOfMemoryError: GC overhead limit exceeded Any ideas?
Clearly the server runs out of memory, which we can't help with without the full code. I suggest analyzing the RAM with a tool like jvisualvm to see what goes wrong.
Its just a memory error check, you can disable that by using this "-XX:-UseGCOverheadLimit" as a start value
1. Holy hell... hop off that dinosaur and stop using 1.7.10... 2. You're using PaperSpigot. We do not support that here. Your questions are better answered over on the PaperSpigot forums, especially considering they make a lot of changes to the server software imposing various limitations @Phloxz sure, that works... but by no means should that limit be reached in the first place. There's clearly something causing that
Just wondering, @joeleoli why don't you open the inventory directly after it closes? so you don't need the task?
InventoryCloseEvent isn't cancellable. Without the tick delay, I am almost sure that errors will occur. That is most likely why he has a tick delay.
https://gyazo.com/2fd69bd756d3338c20b823a89071dd61 Note: this is quite unrelated to OP's issue. But those are the errors that occur when I remove my tick delay inside of my freeze plugin.
Oh no no, I am not having those issues myself, I am just saying that's what happens when you don't have a one tick delay when using openInventory(Inventory); Inside of the InventoryCloseEvent
Ehhh, all the code from the post i see is this: Code (Text): public void open(Player player) { new BukkitRunnable() { public void run() { player.openInventory(inventory); // line 59 of Menu class } }.runTaskLater(jHub.getInstance(), 1L); } So would be better if @joeleoli post his lines in here
Without a tick delay, you get errors upon joining and disconnecting. I've tried profiling it using visualvm but I've been waiting for hours and it still hasn't crashed. It usually takes like 6+ hours. The GC activity and Heap space is in a fixed pattern, so nothing seems abnormal. Inventory close and join listener: Code (Text): @EventHandler(priority = EventPriority.LOWEST) public void onJoin(PlayerJoinEvent event) { event.setJoinMessage(null); final Player player = event.getPlayer(); kickTimes.put(player.getUniqueId(), System.currentTimeMillis() + 15000L); new BukkitRunnable() { public void run() { player.teleport(jHub.getInstance().getSpawn()); } }.runTaskLater(jHub.getInstance(), 1L); for(Player p : Bukkit.getOnlinePlayers()) { p.hidePlayer(player); player.hidePlayer(p); } player.getInventory().clear(); player.teleport(jHub.getInstance().getSpawn()); jHub.getInstance().getMenu().open(player); // Menu is opened here jHub.getInstance().getServerList().get("global").setAmount(jHub.getInstance().getServerList().get("global").getAmount() + 1); } @EventHandler public void onInventoryClose(InventoryCloseEvent event) { jHub.getInstance().getMenu().open((Player)event.getPlayer()); } My Menu class: Code (Text): package me.joeleoli.jhub.menu; import me.joeleoli.jhub.jHub; import me.joeleoli.jhub.utils.ItemBuilder; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.scheduler.BukkitRunnable; import java.util.UUID; public class Menu { private Inventory inventory; public Menu() { inventory = Bukkit.createInventory(null, 27, ChatColor.AQUA + "Click to connect!"); inventory.setItem(0, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(1, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(2, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(3, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(4, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(5, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(6, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(7, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(8, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(9, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(10, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(11, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(12, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(13, new ItemBuilder(Material.DIAMOND_SWORD, ChatColor.AQUA + "Practice " + ChatColor.GRAY + "[US]", ChatColor.GRAY + " » " + ChatColor.AQUA + "Online: " + ChatColor.GRAY + (jHub.getInstance().getServerList().get("Practice").isOnline() ? "True" : "False"), ChatColor.GRAY + " » " + ChatColor.AQUA + "Players: " + ChatColor.GRAY + jHub.getInstance().getServerList().get("Practice").getAmount()).getItem()); inventory.setItem(14, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(15, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(16, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(17, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(18, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(19, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(20, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(21, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(22, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(23, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(24, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 0).getItem()); inventory.setItem(25, new ItemBuilder(Material.STAINED_GLASS_PANE, "", 1, (byte) 3).getItem()); inventory.setItem(26, new ItemBuilder(Material.INK_SACK, ChatColor.RED + "Leave the network", 1, (byte) 1).getItem()); } public void update() { inventory.setItem(13, new ItemBuilder(Material.DIAMOND_SWORD, ChatColor.AQUA + "Practice " + ChatColor.GRAY + "[US]", ChatColor.GRAY + " » " + ChatColor.AQUA + "Online: " + ChatColor.GRAY + (jHub.getInstance().getServerList().get("Practice").isOnline() ? "True" : "False"), ChatColor.GRAY + " » " + ChatColor.AQUA + "Players: " + ChatColor.GRAY + jHub.getInstance().getServerList().get("Practice").getAmount()).getItem()); } public void open(Player player) { new BukkitRunnable() { public void run() { player.openInventory(inventory); } }.runTaskLater(jHub.getInstance(), 1L); } }
Can't see anything leaky, the thing worth pointing out is as above, you're not actually running out of memory, you're just hitting the maximum amount of memory in a GC run that GC will allow occurring before it cries... (Java wants you to avoid high GC pressure, as that drastically hurts your performance). taking a heap-dump might be useful, but if you're running the server on low amounts of memory, might just be a simple case of allocating more memory in order to up the amount of memory that GC has to work.
All i see seems correct, and you are right you have to use a small task at the join event, but you could remove the task at the inventoryClose Event so you get rid of useless tasks that starts to run
Will do. I checked my hub today when I got home, and it seemed to crash after the same amount of time as before. I'm using the following start script: Code (Text): java -Xmx4G -Xms2G -jar paperspigot.jar
This seems questionable Code (Text): @EventHandler public void onInventoryClose(InventoryCloseEvent event) { jHub.getInstance().getMenu().open((Player)event.getPlayer()); } So what if the player logs out? I believe that still triggers the inventory close event. The question is whether the inventory close event is also fired when you open an inventory for a player that is offline.