Added Memory Stat Dumping via pressing p
This commit is contained in:
@@ -19,7 +19,11 @@
|
||||
|
||||
package com.seibel.lod.core.api;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -35,6 +39,7 @@ import com.seibel.lod.core.render.GLProxy;
|
||||
import com.seibel.lod.core.render.LodRenderer;
|
||||
import com.seibel.lod.core.util.DetailDistanceUtil;
|
||||
import com.seibel.lod.core.util.SingletonHandler;
|
||||
import com.seibel.lod.core.util.SpamReducedLogger;
|
||||
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
||||
@@ -52,7 +57,11 @@ import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
|
||||
* @version 12-8-2021
|
||||
*/
|
||||
public class ClientApi
|
||||
{
|
||||
{
|
||||
public static boolean prefLoggerEnabled = false;
|
||||
public static List<WeakReference<SpamReducedLogger>> spamReducedLoggers
|
||||
= Collections.synchronizedList(new LinkedList<WeakReference<SpamReducedLogger>>());
|
||||
|
||||
public static final ClientApi INSTANCE = new ClientApi();
|
||||
public static final Logger LOGGER = LogManager.getLogger(ModInfo.NAME);
|
||||
|
||||
@@ -67,6 +76,8 @@ public class ClientApi
|
||||
public static final boolean ENABLE_LAG_SPIKE_LOGGING = false;
|
||||
public static final long LAG_SPIKE_THRESOLD_NS = TimeUnit.NANOSECONDS.convert(16, TimeUnit.MILLISECONDS);
|
||||
|
||||
public static final long SPAM_LOGGER_FLUSH_NS = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS);
|
||||
|
||||
public static class LagSpikeCatcher {
|
||||
|
||||
long timer = System.nanoTime();
|
||||
@@ -94,6 +105,16 @@ public class ClientApi
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void flushSpamLoggersState() {
|
||||
synchronized(spamReducedLoggers) {
|
||||
spamReducedLoggers.removeIf((logger) -> logger.get()==null);
|
||||
spamReducedLoggers.forEach((logger) -> {
|
||||
SpamReducedLogger l = logger.get();
|
||||
if (l!=null) l.reset();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private final ConcurrentHashMap.KeySetView<Long,Boolean> generating = ConcurrentHashMap.newKeySet();
|
||||
public final ConcurrentHashMap.KeySetView<Long,Boolean> toBeLoaded = ConcurrentHashMap.newKeySet();
|
||||
@@ -106,6 +127,8 @@ public class ClientApi
|
||||
clientChunkLoad.end("clientChunkLoad");
|
||||
}
|
||||
|
||||
private long lastFlush = 0;
|
||||
|
||||
public void renderLods(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks)
|
||||
{
|
||||
// comment out when creating a release
|
||||
@@ -116,6 +139,12 @@ public class ClientApi
|
||||
|
||||
try
|
||||
{
|
||||
if (System.nanoTime() - lastFlush >= SPAM_LOGGER_FLUSH_NS) {
|
||||
lastFlush = System.nanoTime();
|
||||
flushSpamLoggersState();
|
||||
}
|
||||
|
||||
|
||||
// only run the first time setup once
|
||||
if (!firstTimeSetupComplete)
|
||||
firstFrameSetup();
|
||||
@@ -134,6 +163,7 @@ public class ClientApi
|
||||
ApiShared.lodBuilder.defaultDimensionWidthInRegions);
|
||||
ApiShared.lodWorld.addLodDimension(lodDim);
|
||||
}
|
||||
if (prefLoggerEnabled) lodDim.dumpRamUsage();
|
||||
|
||||
LagSpikeCatcher updateToBeLoadedChunk = new LagSpikeCatcher();
|
||||
for (long pos : toBeLoaded) {
|
||||
@@ -267,9 +297,11 @@ public class ClientApi
|
||||
.setDrawLods(!CONFIG.client().advanced().debugging().getDrawLods());
|
||||
MC.sendChatMessage("F6: Set rendering to " + CONFIG.client().advanced().debugging().getDrawLods());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (glfwKey == GLFW.GLFW_KEY_P) {
|
||||
prefLoggerEnabled = !prefLoggerEnabled;
|
||||
MC.sendChatMessage("P: Debug Pref Logger is " + (prefLoggerEnabled ? "enabled" : "disabled"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -122,4 +122,10 @@ public interface LevelContainer
|
||||
*/
|
||||
int getMaxNumberOfLods();
|
||||
|
||||
/**
|
||||
* This will return a ram usage estimation of this object
|
||||
* @return long as byte
|
||||
*/
|
||||
long getRoughRamUsage();
|
||||
|
||||
}
|
||||
|
||||
@@ -26,8 +26,6 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
|
||||
import com.seibel.lod.core.api.ClientApi;
|
||||
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.core.enums.config.DropoffQuality;
|
||||
@@ -44,6 +42,8 @@ import com.seibel.lod.core.util.LodUtil;
|
||||
import com.seibel.lod.core.util.MovabeGridRingList;
|
||||
import com.seibel.lod.core.util.MovabeGridRingList.Pos;
|
||||
import com.seibel.lod.core.util.SingletonHandler;
|
||||
import com.seibel.lod.core.util.SpamReducedLogger;
|
||||
import com.seibel.lod.core.util.UnitBytes;
|
||||
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper;
|
||||
@@ -687,6 +687,44 @@ public class LodDimension
|
||||
generateIteratorList();
|
||||
}
|
||||
|
||||
private final SpamReducedLogger ramLogger = new SpamReducedLogger(1);
|
||||
public void dumpRamUsage()
|
||||
{
|
||||
if (!ramLogger.canMaybeLog()) return;
|
||||
int regionCount = width*width;
|
||||
ramLogger.info("Dumping Ram Usage for LodDim in {} with {} regions...", dimension.getDimensionName(), regionCount);
|
||||
int nonNullRegionCount = 0;
|
||||
int dirtiedRegionCount = 0;
|
||||
long totalUsage = 0;
|
||||
int[] detailCount = new int[LodUtil.DETAIL_OPTIONS];
|
||||
long[] detailUsage = new long[LodUtil.DETAIL_OPTIONS];
|
||||
for (LodRegion r : regions) {
|
||||
if (r==null) continue;
|
||||
nonNullRegionCount++;
|
||||
if (r.needSaving) dirtiedRegionCount++;
|
||||
LevelContainer[] container = r.debugGetDataContainers().clone();
|
||||
if (container == null || container.length != LodUtil.DETAIL_OPTIONS) {
|
||||
ClientApi.LOGGER.warn("DumpRamUsage encountered an invalid region!");
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < LodUtil.DETAIL_OPTIONS; i++) {
|
||||
if (container[i] == null) continue;
|
||||
detailCount[i]++;
|
||||
long byteUsage = container[i].getRoughRamUsage();
|
||||
detailUsage[i] += byteUsage;
|
||||
totalUsage += byteUsage;
|
||||
}
|
||||
}
|
||||
ramLogger.info("================================================");
|
||||
ramLogger.info("Non Null Regions: [{}], Dirtied Regions: [{}], Bytes: [{}]",
|
||||
nonNullRegionCount, dirtiedRegionCount, new UnitBytes(totalUsage));
|
||||
ramLogger.info("------------------------------------------------");
|
||||
for (int i = 0; i < LodUtil.DETAIL_OPTIONS; i++) {
|
||||
ramLogger.info("DETAIL {}: Containers: [{}], Bytes: [{}]", i, detailCount[i], new UnitBytes(detailUsage[i]));
|
||||
}
|
||||
ramLogger.info("================================================");
|
||||
ramLogger.incLogTries();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.seibel.lod.core.util.DataPointUtil;
|
||||
import com.seibel.lod.core.util.DetailDistanceUtil;
|
||||
import com.seibel.lod.core.util.LevelPosUtil;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
import com.seibel.lod.core.util.SpamReducedLogger;
|
||||
|
||||
/**
|
||||
* This object holds all loaded LevelContainers acting as a quad tree for a
|
||||
@@ -610,6 +611,8 @@ public class LodRegion {
|
||||
return dataContainer[detailLevel].getVerticalSize();
|
||||
}
|
||||
|
||||
public LevelContainer[] debugGetDataContainers() {return dataContainer;}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getLevel(LodUtil.REGION_DETAIL_LEVEL).toString();
|
||||
|
||||
@@ -1269,6 +1269,12 @@ public class VerticalLevelContainer implements LevelContainer
|
||||
{
|
||||
return size * size * getVerticalSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRoughRamUsage()
|
||||
{
|
||||
return dataContainer.length * Long.BYTES;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.seibel.lod.core.util;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.seibel.lod.core.api.ClientApi;
|
||||
|
||||
public class SpamReducedLogger {
|
||||
private final int maxLogCount;
|
||||
private final AtomicInteger logTries = new AtomicInteger(0);
|
||||
private int sectionLogCount = -1;
|
||||
public SpamReducedLogger(int maxLogPerSec) {
|
||||
maxLogCount = maxLogPerSec;
|
||||
ClientApi.spamReducedLoggers.add(new WeakReference<SpamReducedLogger>(this));
|
||||
}
|
||||
public void reset() {logTries.set(0);}
|
||||
public boolean canMaybeLog() {return logTries.get() < maxLogCount;}
|
||||
|
||||
public void info(String str, Object... param) {
|
||||
if (sectionLogCount == -1) sectionLogCount = logTries.getAndIncrement();
|
||||
if (sectionLogCount >= maxLogCount) return;
|
||||
ClientApi.LOGGER.info(str, param);
|
||||
}
|
||||
public void debug(String str, Object... param) {
|
||||
if (sectionLogCount == -1) sectionLogCount = logTries.getAndIncrement();
|
||||
if (sectionLogCount >= maxLogCount) return;
|
||||
ClientApi.LOGGER.debug(str, param);
|
||||
}
|
||||
public void warn(String str, Object... param) {
|
||||
if (sectionLogCount == -1) sectionLogCount = logTries.getAndIncrement();
|
||||
if (sectionLogCount >= maxLogCount) return;
|
||||
ClientApi.LOGGER.warn(str, param);
|
||||
}
|
||||
public void error(String str, Object... param) {
|
||||
if (sectionLogCount == -1) sectionLogCount = logTries.getAndIncrement();
|
||||
if (sectionLogCount >= maxLogCount) return;
|
||||
ClientApi.LOGGER.error(str, param);
|
||||
}
|
||||
public void incLogTries() {
|
||||
sectionLogCount = -1;
|
||||
}
|
||||
|
||||
public void infoInc(String str, Object... param) {
|
||||
if (logTries.getAndIncrement() >= maxLogCount) return;
|
||||
ClientApi.LOGGER.info(str, param);
|
||||
}
|
||||
public void debugInc(String str, Object... param) {
|
||||
if (logTries.getAndIncrement() >= maxLogCount) return;
|
||||
ClientApi.LOGGER.debug(str, param);
|
||||
}
|
||||
public void warnInc(String str, Object... param) {
|
||||
if (logTries.getAndIncrement() >= maxLogCount) return;
|
||||
ClientApi.LOGGER.warn(str, param);
|
||||
}
|
||||
public void errorInc(String str, Object... param) {
|
||||
if (logTries.getAndIncrement() >= maxLogCount) return;
|
||||
ClientApi.LOGGER.error(str, param);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.seibel.lod.core.util;
|
||||
|
||||
public class UnitBytes
|
||||
{
|
||||
public final long value;
|
||||
public UnitBytes(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
public static long byteToGB(long v) {
|
||||
return v/1073741824;
|
||||
}
|
||||
public static long byteToMB(long v) {
|
||||
return v/1048576;
|
||||
}
|
||||
public static long byteToKB(long v) {
|
||||
return v/1024;
|
||||
}
|
||||
public static long GBToByte(long v) {
|
||||
return v*1073741824;
|
||||
}
|
||||
public static long MBToByte(long v) {
|
||||
return v*1048576;
|
||||
}
|
||||
public static long KBToByte(long v) {
|
||||
return v*1024;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
long v = value;
|
||||
StringBuilder str = new StringBuilder();
|
||||
long GB = byteToGB(v);
|
||||
if (GB != 0) str.append(GB+ "GB ");
|
||||
v -= GBToByte(GB);
|
||||
long MB = byteToMB(v);
|
||||
if (MB != 0) str.append(MB+ "MB ");
|
||||
v -= MBToByte(MB);
|
||||
long KB = byteToKB(v);
|
||||
if (KB != 0) str.append(KB+ "KB ");
|
||||
v -= KBToByte(KB);
|
||||
str.append(v+"B");
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user