Print a warning if G1GC is used

G1GC is known to cause stuttering
This commit is contained in:
James Seibel
2025-12-13 16:46:59 -06:00
parent 6d3e30d425
commit 016fc66293
4 changed files with 60 additions and 9 deletions
@@ -25,23 +25,16 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.renderer.generic.GenericRenderObjectFactory;
import com.seibel.distanthorizons.core.sql.DatabaseUpdater;
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.core.world.DhApiWorldProxy;
import com.seibel.distanthorizons.core.api.external.methods.config.DhApiConfig;
import com.seibel.distanthorizons.core.api.external.methods.data.DhApiTerrainDataRepo;
import com.seibel.distanthorizons.api.DhApi;
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
import net.jpountz.lz4.LZ4FrameOutputStream;
import org.apache.logging.log4j.LogManager;
import com.seibel.distanthorizons.core.logging.DhLogger;
import org.sqlite.SQLiteJDBCLoader;
import org.sqlite.util.OSInfo;
import org.tukaani.xz.XZOutputStream;
import java.awt.*;
import java.io.File;
/** Handles first time Core setup. */
public class Initializer
{
@@ -56,6 +56,8 @@ import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW;
import java.io.File;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
@@ -93,6 +95,7 @@ public class ClientApi
private boolean isDevBuildMessagePrinted = false;
private boolean lowMemoryWarningPrinted = false;
private boolean highVanillaRenderDistanceWarningPrinted = false;
private boolean g1GarbageCollectorWarningPrinted = false;
private long lastStaticWarningMessageSentMsTime = 0L;
@@ -645,7 +648,8 @@ public class ClientApi
{
// dev build
if (ModInfo.IS_DEV_BUILD
&& !this.isDevBuildMessagePrinted && MC_CLIENT.playerExists())
&& !this.isDevBuildMessagePrinted
&& MC_CLIENT.playerExists())
{
this.isDevBuildMessagePrinted = true;
this.lastStaticWarningMessageSentMsTime = System.currentTimeMillis();
@@ -691,10 +695,11 @@ public class ClientApi
if (!this.highVanillaRenderDistanceWarningPrinted
&& Config.Common.Logging.Warning.showHighVanillaRenderDistanceWarning.get())
{
this.highVanillaRenderDistanceWarningPrinted = true;
// DH generally doesn't need a vanilla render distance above 12
if (MC_RENDER.getRenderDistance() > 12)
{
this.highVanillaRenderDistanceWarningPrinted = true;
this.lastStaticWarningMessageSentMsTime = System.currentTimeMillis();
String message =
@@ -710,6 +715,48 @@ public class ClientApi
MC_CLIENT.sendChatMessage(message);
}
}
// print a warning if G1GC is being used
// (this garbage collector is known to cause stuttering)
if (this.staticStartupMessageSentRecently()) return;
if (!this.g1GarbageCollectorWarningPrinted
&& Config.Common.Logging.Warning.showGarbageCollectorWarning.get())
{
this.g1GarbageCollectorWarningPrinted = true;
try
{
boolean g1GcInUse = false;
List<GarbageCollectorMXBean> gcMxBeans = ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean gcMxBean : gcMxBeans)
{
// "G1 Young Generation" // "G1 Concurrent GC" // "G1 Old Generation"
if (gcMxBean.getName().toLowerCase().contains("g1 "))
{
g1GcInUse = true;
break;
}
}
if (g1GcInUse)
{
ClientApi.INSTANCE.showChatMessageNextFrame(
// yellow text
"\u00A7e" + "Distant Horizons: G1 Garbage collector detected." + "\u00A7r \n" +
"This garbage collector can cause FPS stuttering. \n" +
"It's recommended to use a concurrent garbage collector \n" +
"like ZGC (Java 21+) for a smoother experience. \n" +
"");
}
}
catch (Exception re)
{
LOGGER.warn("Unable to determine garbage collector type. If stuttering occurs please try a concurrent garbage collector like ZGC.");
}
}
}
/** done to prevent sending a bunch of startup messages all at once, causing some to be missed. */
private boolean staticStartupMessageSentRecently()
@@ -1629,6 +1629,15 @@ public class Config
+ "")
.build();
public static ConfigEntry<Boolean> showGarbageCollectorWarning = new ConfigEntry.Builder<Boolean>()
.set(true)
.comment(""
+ "If enabled, a chat message will be displayed if the garbage \n"
+ "collector Java is currently using is known \n"
+ "to cause stutters and/or issues. \n"
+ "")
.build();
public static ConfigEntry<Boolean> showReplayWarningOnStartup = new ConfigEntry.Builder<Boolean>()
.set(true)
.comment(""
@@ -725,6 +725,8 @@
"If DH detects that pooled objects are being garbage collected this will send a chat warning.",
"distanthorizons.config.common.logging.warning.showHighVanillaRenderDistanceWarning":
"Show High Vanilla Render Distance Warning",
"distanthorizons.config.common.logging.warning.showGarbageCollectorWarning":
"Show Garbage Collector Warning",
"distanthorizons.config.common.logging.warning.showReplayWarningOnStartup":
"Show Replay Warning",
"distanthorizons.config.common.logging.warning.showUpdateQueueOverloadedChatWarning":