Add Ram Usage Detector
This commit is contained in:
committed by
Sheepit Renderfarm
parent
2e46685068
commit
1969f57da3
@@ -621,7 +621,7 @@ import okhttp3.HttpUrl;
|
|||||||
StringBuilder logHeader = new StringBuilder()
|
StringBuilder logHeader = new StringBuilder()
|
||||||
.append("====================================================================================================\n")
|
.append("====================================================================================================\n")
|
||||||
.append(String.format("%s / %s / %s / SheepIt v%s\n", conf.getLogin(), conf.getHostname(), OS.getOS().name(), conf.getJarVersion()))
|
.append(String.format("%s / %s / %s / SheepIt v%s\n", conf.getLogin(), conf.getHostname(), OS.getOS().name(), conf.getJarVersion()))
|
||||||
.append(String.format("%s x%d %.1f GB RAM\n", cpu.name(), conf.getNbCores(), conf.getMaxMemory() / 1024.0 / 1024.0));
|
.append(String.format("%s x%d %.1f GB RAM\n", cpu.name(), conf.getNbCores(), conf.getMaxAllowedMemory() / 1024.0 / 1024.0));
|
||||||
|
|
||||||
if (conf.getComputeMethod() == Configuration.ComputeType.GPU || conf.getComputeMethod() == Configuration.ComputeType.CPU_GPU) {
|
if (conf.getComputeMethod() == Configuration.ComputeType.GPU || conf.getComputeMethod() == Configuration.ComputeType.CPU_GPU) {
|
||||||
logHeader.append(String.format("%s %s %.1f GB VRAM\n", conf.getGPUDevice().getId(), conf.getGPUDevice().getModel(),
|
logHeader.append(String.format("%s %s %.1f GB VRAM\n", conf.getGPUDevice().getId(), conf.getGPUDevice().getModel(),
|
||||||
@@ -657,7 +657,7 @@ import okhttp3.HttpUrl;
|
|||||||
remoteURL.addQueryParameter("frame", job_to_reset_.getFrameNumber());
|
remoteURL.addQueryParameter("frame", job_to_reset_.getFrameNumber());
|
||||||
remoteURL.addQueryParameter("job", job_to_reset_.getId());
|
remoteURL.addQueryParameter("job", job_to_reset_.getId());
|
||||||
remoteURL.addQueryParameter("render_time", Integer.toString(job_to_reset_.getProcessRender().getDuration()));
|
remoteURL.addQueryParameter("render_time", Integer.toString(job_to_reset_.getProcessRender().getDuration()));
|
||||||
remoteURL.addQueryParameter("memoryused", Long.toString(job_to_reset_.getProcessRender().getMemoryUsed()));
|
remoteURL.addQueryParameter("memoryused", Long.toString(job_to_reset_.getProcessRender().getPeakMemoryUsed()));
|
||||||
if (job_to_reset_.getExtras() != null && job_to_reset_.getExtras().isEmpty() == false) {
|
if (job_to_reset_.getExtras() != null && job_to_reset_.getExtras().isEmpty() == false) {
|
||||||
remoteURL.addQueryParameter("extras", job_to_reset_.getExtras());
|
remoteURL.addQueryParameter("extras", job_to_reset_.getExtras());
|
||||||
}
|
}
|
||||||
@@ -1017,7 +1017,7 @@ import okhttp3.HttpUrl;
|
|||||||
|
|
||||||
protected Error.Type confirmJob(Job ajob, int checkpoint) {
|
protected Error.Type confirmJob(Job ajob, int checkpoint) {
|
||||||
String url_real = String.format("%s&rendertime=%d&memoryused=%s", ajob.getValidationUrl(), ajob.getProcessRender().getDuration(),
|
String url_real = String.format("%s&rendertime=%d&memoryused=%s", ajob.getValidationUrl(), ajob.getProcessRender().getDuration(),
|
||||||
ajob.getProcessRender().getMemoryUsed());
|
ajob.getProcessRender().getPeakMemoryUsed());
|
||||||
this.log.debug(checkpoint, "Client::confirmeJob url " + url_real);
|
this.log.debug(checkpoint, "Client::confirmeJob url " + url_real);
|
||||||
this.log.debug(checkpoint, "path frame " + ajob.getOutputImagePath());
|
this.log.debug(checkpoint, "path frame " + ajob.getOutputImagePath());
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ import lombok.Data;
|
|||||||
private String proxy;
|
private String proxy;
|
||||||
private int maxUploadingJob;
|
private int maxUploadingJob;
|
||||||
private int nbCores;
|
private int nbCores;
|
||||||
private long maxMemory; // max memory allowed for render
|
private long maxAllowedMemory; // in KiB, max memory allowed for render
|
||||||
private int maxRenderTime; // max render time per frame allowed
|
private int maxRenderTime; // max render time per frame allowed
|
||||||
private int priority;
|
private int priority;
|
||||||
private ComputeType computeMethod;
|
private ComputeType computeMethod;
|
||||||
@@ -83,7 +83,7 @@ import lombok.Data;
|
|||||||
this.static_exeDirName = "exe";
|
this.static_exeDirName = "exe";
|
||||||
this.maxUploadingJob = 1;
|
this.maxUploadingJob = 1;
|
||||||
this.nbCores = -1; // ie not set
|
this.nbCores = -1; // ie not set
|
||||||
this.maxMemory = -1; // ie not set
|
this.maxAllowedMemory = -1; // ie not set
|
||||||
this.maxRenderTime = -1; // ie not set
|
this.maxRenderTime = -1; // ie not set
|
||||||
this.priority = 19; // default lowest
|
this.priority = 19; // default lowest
|
||||||
this.computeMethod = null;
|
this.computeMethod = null;
|
||||||
@@ -109,7 +109,7 @@ import lombok.Data;
|
|||||||
|
|
||||||
public Configuration(Configuration config) {
|
public Configuration(Configuration config) {
|
||||||
this(config.configFilePath, config.workingDirectory, config.sharedDownloadsDirectory, config.storageDirectory, config.userHasSpecifiedACacheDir,
|
this(config.configFilePath, config.workingDirectory, config.sharedDownloadsDirectory, config.storageDirectory, config.userHasSpecifiedACacheDir,
|
||||||
config.static_exeDirName, config.login, config.password, config.proxy, config.maxUploadingJob, config.nbCores, config.maxMemory, config.maxRenderTime,
|
config.static_exeDirName, config.login, config.password, config.proxy, config.maxUploadingJob, config.nbCores, config.maxAllowedMemory, config.maxRenderTime,
|
||||||
config.priority, config.computeMethod, config.GPUDevice, config.renderbucketSize, config.detectGPUs, config.printLog, config.requestTime, config.shutdownTime,
|
config.priority, config.computeMethod, config.GPUDevice, config.renderbucketSize, config.detectGPUs, config.printLog, config.requestTime, config.shutdownTime,
|
||||||
config.shutdownMode, config.extras, config.autoSignIn, config.useSysTray, config.headless, config.UIType, config.hostname, config.theme);
|
config.shutdownMode, config.extras, config.autoSignIn, config.useSysTray, config.headless, config.UIType, config.hostname, config.theme);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ package com.sheepit.client;
|
|||||||
import com.sheepit.client.Configuration.ComputeType;
|
import com.sheepit.client.Configuration.ComputeType;
|
||||||
import com.sheepit.client.Error.Type;
|
import com.sheepit.client.Error.Type;
|
||||||
import com.sheepit.client.hardware.cpu.CPU;
|
import com.sheepit.client.hardware.cpu.CPU;
|
||||||
import com.sheepit.client.hardware.gpu.opencl.OpenCL;
|
|
||||||
import com.sheepit.client.os.OS;
|
import com.sheepit.client.os.OS;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import oshi.software.os.OSProcess;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -133,6 +133,25 @@ import java.util.regex.Pattern;
|
|||||||
frameNumber, sceneMD5, rendererMD5, id, outputImagePath, path, useGPU, name, extras, updateRenderingStatusMethod, render);
|
frameNumber, sceneMD5, rendererMD5, id, outputImagePath, path, useGPU, name, extras, updateRenderingStatusMethod, render);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private OSProcess getRenderOSProcess() {
|
||||||
|
return OS.operatingSystem.getProcess((int) getProcessRender().getProcess().pid());
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getUsedMemory() {
|
||||||
|
OSProcess osp = getRenderOSProcess();
|
||||||
|
return osp != null ? osp.getResidentSetSize() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTotalUsedMemory() {
|
||||||
|
OSProcess osp = getRenderOSProcess();
|
||||||
|
return osp != null ? osp.getVirtualSize() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getThreadCount() {
|
||||||
|
OSProcess osp = getRenderOSProcess();
|
||||||
|
return osp != null ? osp.getThreadCount() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
public String getPrefixOutputImage() {
|
public String getPrefixOutputImage() {
|
||||||
return id + "_";
|
return id + "_";
|
||||||
}
|
}
|
||||||
@@ -284,6 +303,7 @@ import java.util.regex.Pattern;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer memoryCheck = new Timer();
|
||||||
try {
|
try {
|
||||||
renderStartedObservable event = new renderStartedObservable(renderStarted);
|
renderStartedObservable event = new renderStartedObservable(renderStarted);
|
||||||
String line;
|
String line;
|
||||||
@@ -293,6 +313,12 @@ import java.util.regex.Pattern;
|
|||||||
process.start();
|
process.start();
|
||||||
getProcessRender().setProcess(os.exec(command, new_env));
|
getProcessRender().setProcess(os.exec(command, new_env));
|
||||||
BufferedReader input = new BufferedReader(new InputStreamReader(getProcessRender().getProcess().getInputStream()));
|
BufferedReader input = new BufferedReader(new InputStreamReader(getProcessRender().getProcess().getInputStream()));
|
||||||
|
memoryCheck.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
updateRenderingMemoryPeak();
|
||||||
|
}
|
||||||
|
}, 0L, 1000L);
|
||||||
|
|
||||||
// Make initial test/power frames ignore the maximum render time in user configuration. Initial test frames have Job IDs below 20
|
// Make initial test/power frames ignore the maximum render time in user configuration. Initial test frames have Job IDs below 20
|
||||||
// so we just activate the user defined timeout when the scene is not one of the initial ones.
|
// so we just activate the user defined timeout when the scene is not one of the initial ones.
|
||||||
@@ -338,11 +364,10 @@ import java.util.regex.Pattern;
|
|||||||
}
|
}
|
||||||
|
|
||||||
progress = computeRenderingProgress(line, tilePattern, progress);
|
progress = computeRenderingProgress(line, tilePattern, progress);
|
||||||
|
updateRenderingMemoryPeak();
|
||||||
updateRenderingMemoryPeak(line);
|
if (configuration.getMaxAllowedMemory() != -1 && (getUsedMemory() / 1024L) > configuration.getMaxAllowedMemory()) {
|
||||||
if (configuration.getMaxMemory() != -1 && process.getMemoryUsed() > configuration.getMaxMemory()) {
|
log.debug("Blocking render because process ram used (" + (getUsedMemory() / 1024L) + "k) is over user setting (" + configuration
|
||||||
log.debug("Blocking render because process ram used (" + process.getMemoryUsed() + "k) is over user setting (" + configuration
|
.getMaxAllowedMemory() + "k)");
|
||||||
.getMaxMemory() + "k)");
|
|
||||||
OS.getOS().kill(process.getProcess());
|
OS.getOS().kill(process.getProcess());
|
||||||
process.finish();
|
process.finish();
|
||||||
if (script_file != null) {
|
if (script_file != null) {
|
||||||
@@ -369,7 +394,7 @@ import java.util.regex.Pattern;
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!event.isStarted() && (process.getMemoryUsed() > 0 || process.getRemainingDuration() > 0)) {
|
if (!event.isStarted() && (getUsedMemory() > 0 || process.getRemainingDuration() > 0)) {
|
||||||
event.doNotifyIsStarted();
|
event.doNotifyIsStarted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,6 +404,9 @@ import java.util.regex.Pattern;
|
|||||||
// most likely The handle is invalid
|
// most likely The handle is invalid
|
||||||
log.error("Job::render exception(B) (silent error) " + err1);
|
log.error("Job::render exception(B) (silent error) " + err1);
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
|
memoryCheck.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
// Put back base icon
|
// Put back base icon
|
||||||
gui.updateTrayIcon(Job.SHOW_BASE_ICON);
|
gui.updateTrayIcon(Job.SHOW_BASE_ICON);
|
||||||
@@ -580,41 +608,19 @@ import java.util.regex.Pattern;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRenderingMemoryPeak(String line) {
|
private void updateRenderingMemoryPeak() {
|
||||||
String[] elements = line.toLowerCase().split("(peak)");
|
long mem = getUsedMemory() / 1024L; // convert into kB
|
||||||
|
|
||||||
for (String element : elements) {
|
|
||||||
if (!element.isEmpty() && element.charAt(0) == ' ') {
|
|
||||||
int end = element.indexOf(')');
|
|
||||||
if (end > 0) {
|
|
||||||
try {
|
|
||||||
long mem = Utils.parseNumber(element.substring(1, end).trim()) / 1000; // internal use of ram is in kB
|
|
||||||
if (mem > getProcessRender().getMemoryUsed()) {
|
|
||||||
getProcessRender().setMemoryUsed(mem);
|
getProcessRender().setMemoryUsed(mem);
|
||||||
|
if (getProcessRender().getPeakMemoryUsed() < mem) {
|
||||||
|
getProcessRender().setPeakMemoryUsed(mem);
|
||||||
}
|
}
|
||||||
}
|
double memoryConsumed = getUsedMemory() / 1024.0 / 1024.0;
|
||||||
catch (IllegalStateException | NumberFormatException e) {
|
double peakMemoryConsumed = getProcessRender().getPeakMemoryUsed() / 1024.0;
|
||||||
// failed to parseNumber
|
double totalUsedMemory = getTotalUsedMemory() / 1024.0 / 1024.0;
|
||||||
}
|
double systemMemoryAvailable = OS.getOS().getFreeMemory() / 1024.0;
|
||||||
}
|
int threadCount = getThreadCount();
|
||||||
}
|
log.debug(String.format("RAM Consumed: %(,.2fMB | Peak RAM Consumed: %(,.2fMB | Virtual Mem Consumed: %(,.2fMB | System Available Memory: %(,.2fMB | Thread Count: %d",
|
||||||
else {
|
memoryConsumed, peakMemoryConsumed, totalUsedMemory, systemMemoryAvailable, threadCount));
|
||||||
if (!element.isEmpty() && element.charAt(0) == ':') {
|
|
||||||
int end = element.indexOf('|');
|
|
||||||
if (end > 0) {
|
|
||||||
try {
|
|
||||||
long mem = Utils.parseNumber(element.substring(1, end).trim()) / 1000; // internal use of ram is in kB
|
|
||||||
if (mem > getProcessRender().getMemoryUsed()) {
|
|
||||||
getProcessRender().setMemoryUsed(mem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IllegalStateException | NumberFormatException e) {
|
|
||||||
// failed to parseNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type detectError(String line) {
|
private Type detectError(String line) {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import java.util.Date;
|
|||||||
private long endTime;
|
private long endTime;
|
||||||
private int remainingDuration; // in seconds
|
private int remainingDuration; // in seconds
|
||||||
private long memoryUsed; // in kB
|
private long memoryUsed; // in kB
|
||||||
|
private long peakMemoryUsed; // in kB
|
||||||
private int coresUsed;
|
private int coresUsed;
|
||||||
private Process process;
|
private Process process;
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ import java.util.Date;
|
|||||||
startTime = -1;
|
startTime = -1;
|
||||||
endTime = -1;
|
endTime = -1;
|
||||||
memoryUsed = 0;
|
memoryUsed = 0;
|
||||||
|
peakMemoryUsed = 0;
|
||||||
coresUsed = 0;
|
coresUsed = 0;
|
||||||
remainingDuration = 0;
|
remainingDuration = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import java.util.stream.Collectors;
|
|||||||
import com.sheepit.client.datamodel.SpeedTestTarget;
|
import com.sheepit.client.datamodel.SpeedTestTarget;
|
||||||
import com.sheepit.client.datamodel.SpeedTestResult;
|
import com.sheepit.client.datamodel.SpeedTestResult;
|
||||||
import com.sheepit.client.datamodel.SpeedTestTargetResult;
|
import com.sheepit.client.datamodel.SpeedTestTargetResult;
|
||||||
|
import com.sheepit.client.os.Windows;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.simpleframework.xml.core.Persister;
|
import org.simpleframework.xml.core.Persister;
|
||||||
|
|
||||||
@@ -205,7 +206,7 @@ public class Server extends Thread {
|
|||||||
.add("cpu_cores", String.valueOf(user_config.getNbCores() == -1 ? os.getCPU().cores() : Math.max(CPU.MIN_CORES, user_config.getNbCores())))
|
.add("cpu_cores", String.valueOf(user_config.getNbCores() == -1 ? os.getCPU().cores() : Math.max(CPU.MIN_CORES, user_config.getNbCores())))
|
||||||
.add("os", os.name())
|
.add("os", os.name())
|
||||||
.add("os_version", os.getVersion())
|
.add("os_version", os.getVersion())
|
||||||
.add("ram", String.valueOf(os.getMemory()))
|
.add("ram", String.valueOf(os.getTotalMemory()))
|
||||||
.add("bits", os.getCPU().arch())
|
.add("bits", os.getCPU().arch())
|
||||||
.add("version", user_config.getJarVersion())
|
.add("version", user_config.getJarVersion())
|
||||||
.add("hostname", user_config.getHostname())
|
.add("hostname", user_config.getHostname())
|
||||||
@@ -305,8 +306,8 @@ public class Server extends Thread {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
OS os = OS.getOS();
|
OS os = OS.getOS();
|
||||||
long maxMemory = this.user_config.getMaxMemory();
|
long maxMemory = this.user_config.getMaxAllowedMemory();
|
||||||
long freeMemory = os.getFreeMemory();
|
long freeMemory = os.getFreeMemory() - 1024^2 /*One gigabyte*/ * (os instanceof Windows ? 2 : 1); //Make RAM to reserve 2GB on Windows
|
||||||
if (maxMemory < 0) {
|
if (maxMemory < 0) {
|
||||||
maxMemory = freeMemory;
|
maxMemory = freeMemory;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -524,8 +524,8 @@ public class SettingsLoader {
|
|||||||
config.setNbCores(Integer.parseInt(cores.getValue()));
|
config.setNbCores(Integer.parseInt(cores.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.getMaxMemory() == -1 && ram != null) {
|
if (config.getMaxAllowedMemory() == -1 && ram != null) {
|
||||||
config.setMaxMemory(Utils.parseNumber(ram.getValue()) / 1000); // internal ram value is in kB
|
config.setMaxAllowedMemory(Utils.parseNumber(ram.getValue()) / 1024); // internal ram value is in KiB
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.getMaxRenderTime() == -1 && renderTime != null) {
|
if (config.getMaxRenderTime() == -1 && renderTime != null) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import com.sheepit.client.hardware.cpu.CPU;
|
|||||||
public abstract class OS {
|
public abstract class OS {
|
||||||
private static SystemInfo systemInfo = new SystemInfo();
|
private static SystemInfo systemInfo = new SystemInfo();
|
||||||
|
|
||||||
static OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
|
public static OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
|
||||||
|
|
||||||
private static HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
|
private static HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ public abstract class OS {
|
|||||||
return (name() + " " + operatingSystem.getVersionInfo()).toLowerCase();
|
return (name() + " " + operatingSystem.getVersionInfo()).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getMemory() {
|
public long getTotalMemory() {
|
||||||
return hardwareAbstractionLayer.getMemory().getTotal() / 1024;
|
return hardwareAbstractionLayer.getMemory().getTotal() / 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ public class Worker {
|
|||||||
|
|
||||||
if (max_ram != null) {
|
if (max_ram != null) {
|
||||||
try {
|
try {
|
||||||
config.setMaxMemory(Utils.parseNumber(max_ram) / 1000); // internal value are in kB
|
config.setMaxAllowedMemory(Utils.parseNumber(max_ram) / 1024); // internal value is in KiB
|
||||||
}
|
}
|
||||||
catch (java.lang.IllegalStateException e) {
|
catch (java.lang.IllegalStateException e) {
|
||||||
System.err.println(
|
System.err.println(
|
||||||
|
|||||||
@@ -407,7 +407,7 @@ public class Settings implements Activity {
|
|||||||
|
|
||||||
// max ram allowed to render
|
// max ram allowed to render
|
||||||
OS os = OS.getOS();
|
OS os = OS.getOS();
|
||||||
int all_ram = (int) os.getMemory();
|
int all_ram = (int) os.getTotalMemory();
|
||||||
ram = new JSlider(0, all_ram);
|
ram = new JSlider(0, all_ram);
|
||||||
int step = 1000000;
|
int step = 1000000;
|
||||||
double display = (double) all_ram / (double) step;
|
double display = (double) all_ram / (double) step;
|
||||||
@@ -428,7 +428,7 @@ public class Settings implements Activity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
ram.setPaintLabels(true);
|
ram.setPaintLabels(true);
|
||||||
ram.setValue((int) (config.getMaxMemory() != -1 ? config.getMaxMemory() : os.getMemory()));
|
ram.setValue((int) (config.getMaxAllowedMemory() != -1 ? config.getMaxAllowedMemory() : os.getTotalMemory()));
|
||||||
JLabel ramLabel = new JLabel("Memory:");
|
JLabel ramLabel = new JLabel("Memory:");
|
||||||
ramLabel.setToolTipText(SwingTooltips.MEMORY.getText());
|
ramLabel.setToolTipText(SwingTooltips.MEMORY.getText());
|
||||||
|
|
||||||
@@ -798,7 +798,7 @@ public class Settings implements Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (max_ram > 0) {
|
if (max_ram > 0) {
|
||||||
config.setMaxMemory(max_ram);
|
config.setMaxAllowedMemory(max_ram);
|
||||||
}
|
}
|
||||||
|
|
||||||
int max_rendertime = -1;
|
int max_rendertime = -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user