Add failsafe for low RAM issue.
This commit is contained in:
@@ -205,6 +205,11 @@ public class LodBuilder
|
||||
region.isWriting++;
|
||||
try {
|
||||
if (region.getMinDetailLevel()!= 0) {
|
||||
if (!LodUtil.checkRamUsage(0.05, 16)) {
|
||||
ClientApi.LOGGER.warn("LodBuilder: Not enough RAM avalible for building lods! Skipping...");
|
||||
return false;
|
||||
}
|
||||
|
||||
LodRegion newRegion = lodDim.getRegionFromFile(region, (byte)0, region.getVerticalQuality());
|
||||
if (region!=newRegion)
|
||||
throw new RuntimeException();
|
||||
|
||||
@@ -83,6 +83,8 @@ public class BatchGenerator {
|
||||
generationGroup.updateAllFutures();
|
||||
if (!MC.hasSinglePlayerServer())
|
||||
return;
|
||||
if (!LodUtil.checkRamUsage(0.1, 64)) return;
|
||||
|
||||
int eventsCount = generationGroup.getEventCount();
|
||||
// If we still all jobs running, return.
|
||||
if (eventsCount >= estimatedPointsToQueue) {
|
||||
|
||||
@@ -26,6 +26,8 @@ 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;
|
||||
@@ -316,12 +318,21 @@ public class LodDimension
|
||||
};
|
||||
cutAndExpandThread.execute(thread);
|
||||
}
|
||||
|
||||
|
||||
private boolean expandOrLoadPaused = false;
|
||||
/** Either expands or loads all regions in the rendered LOD area */
|
||||
public void expandOrLoadRegionsAsync(int playerPosX, int playerPosZ) {
|
||||
|
||||
if (isExpanding) return;
|
||||
// We have less than 10% or 1MB ram left. Don't expend.
|
||||
if (expandOrLoadPaused && !LodUtil.checkRamUsage(0.4, 512)) {
|
||||
//ClientApi.LOGGER.info("Not enough ram for expandOrLoadThread. Skipping...");
|
||||
return;
|
||||
} else if (expandOrLoadPaused) {
|
||||
ClientApi.LOGGER.info("Enough ram for expandOrLoadThread. Restarting...");
|
||||
}
|
||||
isExpanding = true;
|
||||
expandOrLoadPaused = false;
|
||||
|
||||
VerticalQuality verticalQuality = CONFIG.client().graphics().quality().getVerticalQuality();
|
||||
DropoffQuality dropoffQuality = CONFIG.client().graphics().quality().getDropoffQuality();
|
||||
@@ -333,9 +344,19 @@ public class LodDimension
|
||||
// for the same location
|
||||
Runnable thread = () -> {
|
||||
//ClientApi.LOGGER.info("LodDim expend Region: " + playerPosX + "," + playerPosZ);
|
||||
|
||||
Pos minPos = regions.getMinInRange();
|
||||
iterateWithSpiral((int x, int z) -> {
|
||||
if (expandOrLoadPaused) return;
|
||||
if (!LodUtil.checkRamUsage(0.1, 32)) {
|
||||
Runtime.getRuntime().gc();
|
||||
if (!LodUtil.checkRamUsage(0.2, 64)) {
|
||||
ClientApi.LOGGER.warn("Not enough ram for expandOrLoadThread. Pausing until Ram is freed...");
|
||||
// We have less than 10% or 1MB ram left. Don't expend.
|
||||
expandOrLoadPaused = true;
|
||||
saveDirtyRegionsToFile(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
int regionX;
|
||||
int regionZ;
|
||||
LodRegion region;
|
||||
@@ -355,8 +376,8 @@ public class LodDimension
|
||||
playerPosZ);
|
||||
minDetail = DetailDistanceUtil.getDetailLevelFromDistance(minDistance);
|
||||
maxDetail = DetailDistanceUtil.getDetailLevelFromDistance(maxDistance);
|
||||
|
||||
boolean updated = false;
|
||||
boolean expended = false;
|
||||
if (region == null) {
|
||||
region = getRegionFromFile(regionPos, minDetail, verticalQuality);
|
||||
regions.set(regionX, regionZ, region);
|
||||
|
||||
@@ -56,6 +56,7 @@ public class DetailDistanceUtil
|
||||
maxDistance = CONFIG.client().graphics().quality().getLodChunkRenderDistance() * 16 * 8;
|
||||
}
|
||||
|
||||
/*// Need UPDATE and BUG FIX
|
||||
public static int baseDistanceFunction(int detail)
|
||||
{
|
||||
if (detail <= minGenDetail)
|
||||
@@ -79,11 +80,11 @@ public class DetailDistanceUtil
|
||||
public static int getDrawDistanceFromDetail(int detail)
|
||||
{
|
||||
return baseDistanceFunction(detail);
|
||||
}
|
||||
}*/
|
||||
|
||||
public static byte baseInverseFunction(int distance, byte minDetail)
|
||||
{
|
||||
byte detail;
|
||||
int detail;
|
||||
distance -= minDetailDistance;
|
||||
|
||||
if (distance < 0 || CONFIG.client().graphics().advancedGraphics().getAlwaysDrawAtMaxQuality())
|
||||
@@ -92,12 +93,12 @@ public class DetailDistanceUtil
|
||||
double scaledDistance = distance;
|
||||
scaledDistance /= distanceUnit;
|
||||
if (CONFIG.client().graphics().quality().getHorizontalQuality() == HorizontalQuality.LOWEST)
|
||||
detail = (byte) (scaledDistance);
|
||||
detail = (int) (scaledDistance);
|
||||
else
|
||||
{
|
||||
double base = CONFIG.client().graphics().quality().getHorizontalQuality().quadraticBase;
|
||||
double logBase = Math.log(base);
|
||||
detail = (byte) (Math.log(scaledDistance) / logBase);
|
||||
detail = (int) (Math.log(scaledDistance) / logBase);
|
||||
}
|
||||
return (byte) LodUtil.clamp(minDetail, detail+minDetail, maxDetail - 1);
|
||||
}
|
||||
|
||||
@@ -434,4 +434,15 @@ public class LodUtil
|
||||
numb = Float.intBitsToFloat(i);
|
||||
return numb * (1.5F - half * numb * numb);
|
||||
}
|
||||
|
||||
// True if the requested threshold pass, or false otherwise
|
||||
// For details, see:
|
||||
// https://stackoverflow.com/questions/3571203/what-are-runtime-getruntime-totalmemory-and-freememory
|
||||
public static boolean checkRamUsage(double minFreeMemoryPercent, int minFreeMemoryMB) {
|
||||
long freeMem = Runtime.getRuntime().freeMemory() + Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory();
|
||||
if (freeMem < minFreeMemoryMB * 1024 * 1024) return false;
|
||||
long maxMem = Runtime.getRuntime().maxMemory();
|
||||
if (freeMem/(double)maxMem < minFreeMemoryPercent) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user