Fixed a memory leak of the notify player instance.

This commit is contained in:
LeonTG77 2016-07-03 13:25:29 +02:00
parent c5df3417c8
commit a053cefb3f
3 changed files with 35 additions and 20 deletions

View File

@ -6,8 +6,10 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.entity.Player;
import org.bukkit.Bukkit;
import org.bukkit.World;
// image output stuff, for debugging method at bottom of this file
@ -23,13 +25,13 @@ public class WorldFileData
private transient World world;
private transient File regionFolder = null;
private transient File[] regionFiles = null;
private transient Player notifyPlayer = null;
private transient UUID notifyPlayerUUID = null;
private transient Map<CoordXZ, List<Boolean>> regionChunkExistence = Collections.synchronizedMap(new HashMap<CoordXZ, List<Boolean>>());
// Use this static method to create a new instance of this class. If null is returned, there was a problem so any process relying on this should be cancelled.
public static WorldFileData create(World world, Player notifyPlayer)
public static WorldFileData create(World world, UUID notifyPlayerUUID)
{
WorldFileData newData = new WorldFileData(world, notifyPlayer);
WorldFileData newData = new WorldFileData(world, notifyPlayerUUID);
newData.regionFolder = new File(newData.world.getWorldFolder(), "region");
if (!newData.regionFolder.exists() || !newData.regionFolder.isDirectory())
@ -68,10 +70,10 @@ public class WorldFileData
}
// the constructor is private; use create() method above to create an instance of this class.
private WorldFileData(World world, Player notifyPlayer)
private WorldFileData(World world, UUID notifyPlayerUUID)
{
this.world = world;
this.notifyPlayer = notifyPlayer;
this.notifyPlayerUUID = notifyPlayerUUID;
}
@ -220,7 +222,10 @@ public class WorldFileData
private void sendMessage(String text)
{
Config.log("[WorldData] " + text);
if (notifyPlayer != null && notifyPlayer.isOnline())
Player notifyPlayer = Bukkit.getPlayer(notifyPlayerUUID);
if (notifyPlayer != null)
notifyPlayer.sendMessage("[WorldData] " + text);
}

View File

@ -4,12 +4,13 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.entity.Player;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Player;
import com.wimbli.WorldBorder.Events.WorldBorderFillFinishedEvent;
import com.wimbli.WorldBorder.Events.WorldBorderFillStartEvent;
@ -26,7 +27,7 @@ public class WorldFillTask implements Runnable
private transient boolean paused = false;
private transient boolean pausedForMemory = false;
private transient int taskID = -1;
private transient Player notifyPlayer = null;
private transient UUID notifyPlayerUUID = null;
private transient int chunksPerRun = 1;
private transient boolean continueNotice = false;
private transient boolean forceLoad = false;
@ -62,7 +63,7 @@ public class WorldFillTask implements Runnable
public WorldFillTask(Server theServer, Player player, String worldName, int fillDistance, int chunksPerRun, int tickFrequency, boolean forceLoad)
{
this.server = theServer;
this.notifyPlayer = player;
this.notifyPlayerUUID = player.getUniqueId();
this.fillDistance = fillDistance;
this.tickFrequency = tickFrequency;
this.chunksPerRun = chunksPerRun;
@ -88,7 +89,7 @@ public class WorldFillTask implements Runnable
}
// load up a new WorldFileData for the world in question, used to scan region files for which chunks are already fully generated and such
worldData = WorldFileData.create(world, notifyPlayer);
worldData = WorldFileData.create(world, notifyPlayerUUID);
if (worldData == null)
{
this.stop();
@ -407,8 +408,11 @@ public class WorldFillTask implements Runnable
int availMem = Config.AvailableMemory();
Config.log("[Fill] " + text + " (free mem: " + availMem + " MB)");
if (notifyPlayer != null)
notifyPlayer.sendMessage("[Fill] " + text);
Player notifyPlayer = Bukkit.getPlayer(notifyPlayerUUID);
if (notifyPlayer != null)
notifyPlayer.sendMessage("[Fill] " + text);
if (availMem < 200)
{ // running low on memory, auto-pause
@ -416,8 +420,10 @@ public class WorldFillTask implements Runnable
Config.StoreFillTask();
text = "Available memory is very low, task is pausing. A cleanup will be attempted now, and the task will automatically continue if/when sufficient memory is freed up.\n Alternatively, if you restart the server, this task will automatically continue once the server is back up.";
Config.log("[Fill] " + text);
if (notifyPlayer != null)
notifyPlayer.sendMessage("[Fill] " + text);
if (notifyPlayer != null)
notifyPlayer.sendMessage("[Fill] " + text);
// prod Java with a request to go ahead and do GC to clean unloaded chunks from memory; this seems to work wonders almost immediately
// yes, explicit calls to System.gc() are normally bad, but in this case it otherwise can take a long long long time for Java to recover memory
System.gc();

View File

@ -6,11 +6,12 @@ import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Player;
import com.wimbli.WorldBorder.Events.WorldBorderTrimFinishedEvent;
import com.wimbli.WorldBorder.Events.WorldBorderTrimStartEvent;
@ -26,7 +27,7 @@ public class WorldTrimTask implements Runnable
private transient boolean readyToGo = false;
private transient boolean paused = false;
private transient int taskID = -1;
private transient Player notifyPlayer = null;
private transient UUID notifyPlayerUUID = null;
private transient int chunksPerRun = 1;
// values for what chunk in the current region we're at
@ -49,7 +50,7 @@ public class WorldTrimTask implements Runnable
public WorldTrimTask(Server theServer, Player player, String worldName, int trimDistance, int chunksPerRun)
{
this.server = theServer;
this.notifyPlayer = player;
this.notifyPlayerUUID = player.getUniqueId();
this.chunksPerRun = chunksPerRun;
this.world = server.getWorld(worldName);
@ -74,7 +75,7 @@ public class WorldTrimTask implements Runnable
this.border.setRadiusX(border.getRadiusX() + trimDistance);
this.border.setRadiusZ(border.getRadiusZ() + trimDistance);
worldData = WorldFileData.create(world, notifyPlayer);
worldData = WorldFileData.create(world, notifyPlayerUUID);
if (worldData == null)
{
this.stop();
@ -399,8 +400,11 @@ public class WorldTrimTask implements Runnable
private void sendMessage(String text)
{
Config.log("[Trim] " + text);
if (notifyPlayer != null)
notifyPlayer.sendMessage("[Trim] " + text);
Player notifyPlayer = Bukkit.getPlayer(notifyPlayerUUID);
if (notifyPlayer != null)
notifyPlayer.sendMessage("[Trim] " + text);
}
/**