Skip to content

Commit

Permalink
Implement world cleaning
Browse files Browse the repository at this point in the history
Signed-off-by: Ross Allan <rallanpcl@gmail.com>
  • Loading branch information
LunNova committed Feb 3, 2013
1 parent ba3e901 commit c53dcf8
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 4 deletions.
3 changes: 3 additions & 0 deletions resources/patches-deobfuscated.xml
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@
</class>
</minecraftCommon>
<forge>
<class id="net.minecraftforge.common.DimensionManager">
<addAll fromClass="me.nallar.patched.PatchDimensionManager"/>
</class>
<class id="net.minecraftforge.common.ForgeChunkManager">
<addAll fromClass="me.nallar.patched.PatchForgeChunkManager"/>
</class>
Expand Down
39 changes: 39 additions & 0 deletions src/common/me/nallar/patched/PatchDimensionManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package me.nallar.patched;

import java.util.Hashtable;
import java.util.logging.Level;

import cpw.mods.fml.common.FMLLog;
import me.nallar.tickthreading.minecraft.TickThreading;
import me.nallar.unsafe.UnsafeUtil;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.WorldEvent;

public class PatchDimensionManager extends DimensionManager {
public static void unloadWorlds(Hashtable<Integer, long[]> worldTickTimes) {
for (int id : unloadQueue) {
WorldServer w = worlds.get(id);
try {
if (w != null) {
w.saveAllChunks(true, null);
} else {
FMLLog.warning("Unexpected world unload - world %d is already unloaded", id);
}
} catch (Exception e) {
FMLLog.log(Level.SEVERE, e, "Exception saving chunks when unloading world " + w);
} finally {
if (w != null) {
MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(w));
w.flush();
setWorld(id, null);
if (TickThreading.instance.cleanWorlds) {
UnsafeUtil.clean(w);
}
}
}
}
unloadQueue.clear();
}
}
2 changes: 1 addition & 1 deletion src/common/me/nallar/patched/PatchPlayerManagerForge.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void updatePlayerInstances() {
}
}
this.chunkWatcherWithPlayers.clear();
} finally {
} finally {
playersUpdateLock.unlock();
}

Expand Down
7 changes: 6 additions & 1 deletion src/common/me/nallar/patched/PatchWorldServer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.nallar.patched;

import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.Random;

Expand Down Expand Up @@ -122,7 +123,11 @@ public void run() {
if (!chunkCoordIterator.hasNext()) {
break;
}
var4 = (ChunkCoordIntPair) chunkCoordIterator.next();
try {
var4 = (ChunkCoordIntPair) chunkCoordIterator.next();
} catch (ConcurrentModificationException e) {
break;
}
}

int cX = var4.chunkXPos;
Expand Down
2 changes: 2 additions & 0 deletions src/common/me/nallar/tickthreading/minecraft/TickManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import me.nallar.tickthreading.minecraft.tickregion.TickRegion;
import me.nallar.tickthreading.minecraft.tickregion.TileEntityTickRegion;
import me.nallar.tickthreading.util.TableFormatter;
import me.nallar.unsafe.UnsafeUtil;
import net.minecraft.entity.Entity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
Expand Down Expand Up @@ -253,6 +254,7 @@ public void unload() {
tickRegions.clear();
entityList.clear();
entityClassToCountMap.clear();
UnsafeUtil.clean(this);
}

public void writeStats(TableFormatter tf) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public class TickThreading {
public boolean concurrentNetworkTicks = false;
public boolean antiCheatKick = false;
public boolean antiCheatNotify = false;
public boolean cleanWorlds = true;

public TickThreading() {
Log.LOGGER.getLevel(); // Force log class to load
Expand Down Expand Up @@ -148,6 +149,8 @@ public void preInit(FMLPreInitializationEvent event) {
antiCheatKickProperty.comment = "Whether to kick players for detected cheating";
Property antiCheatNotifyProperty = config.get(Configuration.CATEGORY_GENERAL, "antiCheatNotify", antiCheatNotify);
antiCheatNotifyProperty.comment = "Whether to notify admins if TT anti-cheat detects cheating";
Property cleanWorldsProperty = config.get(Configuration.CATEGORY_GENERAL, "cleanWorlds", cleanWorlds);
cleanWorldsProperty.comment = "Whether to clean worlds on unload - this should fix some memory leaks due to mods holding on to world objects";
config.save();

TicksCommand.name = ticksCommandName.value;
Expand Down Expand Up @@ -176,6 +179,7 @@ public void preInit(FMLPreInitializationEvent event) {
concurrentNetworkTicks = concurrentNetworkTicksProperty.getBoolean(concurrentNetworkTicks);
antiCheatKick = antiCheatKickProperty.getBoolean(antiCheatKick);
antiCheatNotify = antiCheatNotifyProperty.getBoolean(antiCheatNotify);
cleanWorlds = cleanWorldsProperty.getBoolean(cleanWorlds);
int[] disabledDimensions = disabledFastMobSpawningDimensionsProperty.getIntList();
disabledFastMobSpawningDimensions = new HashSet<Integer>(disabledDimensions.length);
for (int disabledDimension : disabledDimensions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

Expand All @@ -18,7 +17,6 @@ public class EntityTickProfiler {
private int ticks;
private StringBuffer slowTicks = new StringBuffer(); // buffer for threadsafety


public void record(Object o, long time) {
if (time < 0) {
time = 0;
Expand Down
20 changes: 20 additions & 0 deletions src/common/me/nallar/unsafe/UnsafeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,24 @@ public static void main(String[] args) {
UnsafeUtil.swap(a, b);
Log.info(compare(a, b));
}

public static void clean(Object o) {
//Log.info("Clearing " + o.getClass() + '@' + System.identityHashCode(o));
Class c = o.getClass();
while (c != null) {
for (Field field : c.getDeclaredFields()) {
if (field.getType().isPrimitive() || (field.getModifiers() & Modifier.STATIC) == Modifier.STATIC) {
continue;
}
try {
field.setAccessible(true);
field.set(o, null);
//Log.info("Cleaned field " + MappingUtil.debobfuscate(field.getType().getName()) + ':' + field.getName());
} catch (IllegalAccessException e) {
Log.warning("Exception cleaning " + o.getClass() + '@' + System.identityHashCode(o), e);
}
}
c = c.getSuperclass();
}
}
}

0 comments on commit c53dcf8

Please sign in to comment.