X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=getdown%2Fsrc%2Fgetdown%2Fcore%2Fsrc%2Fmain%2Fjava%2Fjalview%2Fbin%2FMemorySetting.java;h=ac1ac28067870be8e0d6a7a8ba76d5dd6f07ef53;hb=5911188c77dae6665babf4041dc11484f4a09a0b;hp=8af09da6dc821a2b547481c7448ed0340af4d8d5;hpb=fb97a6a7e2f0c39910f283d858b185514521f1b5;p=jalview.git diff --git a/getdown/src/getdown/core/src/main/java/jalview/bin/MemorySetting.java b/getdown/src/getdown/core/src/main/java/jalview/bin/MemorySetting.java index 8af09da..ac1ac28 100644 --- a/getdown/src/getdown/core/src/main/java/jalview/bin/MemorySetting.java +++ b/getdown/src/getdown/core/src/main/java/jalview/bin/MemorySetting.java @@ -1,51 +1,177 @@ package jalview.bin; -import java.lang.management.ManagementFactory; -import java.lang.management.OperatingSystemMXBean; - public class MemorySetting { public static final long leaveFreeMinMemory = 536870912; // 0.5 GB public static final long applicationMinMemory = 536870912; // 0.5 GB - protected static long getPhysicalMemory() + private final static int maxHeapSizePerCentDefault = 90; + + public final static String maxHeapSizePerCentProperty = "jvmmempc"; + + private final static long maxHeapSizeDefault = 34359738368L; // 32GB + + private final static long noMemMaxHeapSizeDefault = 8589934592L; // 8GB + + public final static String maxHeapSizeProperty = "jvmmemmax"; + + public static long getMemorySetting() { - final OperatingSystemMXBean o = ManagementFactory - .getOperatingSystemMXBean(); + return getMemorySetting(null, null); + } - try + public static long getMemorySetting(String jvmmemmaxString, + String jvmmempcString) + { + // actual Xmx value-to-be + long maxMemLong = -1; + + // get (absolute) jvmmaxmem setting + long memmax = maxHeapSizeDefault; + String jvmmemmaxorig = jvmmemmaxString; + if (jvmmemmaxorig == null) + { + jvmmemmaxorig = System.getProperty(maxHeapSizeProperty); + } + String jvmmemmax = jvmmemmaxorig; + if (jvmmemmax != null && jvmmemmax.length() > 0) { - if (o instanceof com.sun.management.OperatingSystemMXBean) + long multiplier = 1; + switch (jvmmemmax.toLowerCase().substring(jvmmemmax.length() - 1)) + { + case "t": + multiplier = 1099511627776L; // 2^40 + jvmmemmax = jvmmemmax.substring(0, jvmmemmax.length() - 1); + break; + case "g": + multiplier = 1073741824; // 2^30 + jvmmemmax = jvmmemmax.substring(0, jvmmemmax.length() - 1); + break; + case "m": + multiplier = 1048576; // 2^20 + jvmmemmax = jvmmemmax.substring(0, jvmmemmax.length() - 1); + break; + case "k": + multiplier = 1024; // 2^10 + jvmmemmax = jvmmemmax.substring(0, jvmmemmax.length() - 1); + break; + case "b": + multiplier = 1; // 2^0 + jvmmemmax = jvmmemmax.substring(0, jvmmemmax.length() - 1); + break; + default: + break; + } + + // parse the arg + try + { + memmax = Long.parseLong(jvmmemmax); + } catch (NumberFormatException e) + { + memmax = maxHeapSizeDefault; + System.out.println("MemorySetting Property '" + maxHeapSizeProperty + + "' (" + + jvmmemmaxorig + "') badly formatted, using default (" + + memmax + ")."); + } + + // apply multiplier if not too big (i.e. bigger than a long) + if (Long.MAX_VALUE / memmax < multiplier) + { + memmax = maxHeapSizeDefault; + System.out.println( + "MemorySetting Property '" + maxHeapSizeProperty + "' (" + + jvmmemmaxorig + + ") too big, using default (" + memmax + ")."); + } + else + { + memmax = multiplier * memmax; + } + + // check at least minimum value (this accounts for negatives too) + if (memmax < MemorySetting.applicationMinMemory) { - final com.sun.management.OperatingSystemMXBean osb = (com.sun.management.OperatingSystemMXBean) o; - return osb.getTotalPhysicalMemorySize(); + memmax = MemorySetting.applicationMinMemory; + System.out.println( + "MemorySetting Property '" + maxHeapSizeProperty + "' (" + + jvmmemmaxorig + + ") too small, using minimum (" + memmax + ")."); } - } catch (NoClassDefFoundError e) + + } + else { - // com.sun.management.OperatingSystemMXBean doesn't exist in this JVM - System.err.println("No com.sun.management.OperatingSystemMXBean"); + // no need to warn if no setting + // System.out.println("MemorySetting Property '" + maxHeapSizeProperty + "' not + // set."); } - // We didn't get a com.sun.management.OperatingSystemMXBean. - return -1; - } + // get max percent of physical memory + float percent = maxHeapSizePerCentDefault; + String jvmmempc = jvmmempcString; + if (jvmmempc == null) + { + jvmmempc = System.getProperty(maxHeapSizePerCentProperty); + } + long pcmem = -1; + try + { + if (jvmmempc != null) + { + float trypercent = Float.parseFloat(jvmmempc); + if (0 < trypercent && trypercent <= 100f) + { + percent = trypercent; + } + else + { + System.out.println( + "MemorySetting Property '" + maxHeapSizePerCentProperty + + "' should be in range 1..100"); + } + } + } catch (NumberFormatException e) + { + System.out.println( + "MemorySetting property '" + maxHeapSizePerCentProperty + + "' (" + jvmmempc + ") badly formatted"); + } - public static long memPercent(int percent) - { - long memPercent = -1; + // catch everything in case of no com.sun.management.OperatingSystemMXBean + boolean memoryPercentError = false; + try + { + pcmem = MemoryPercent.memPercent(percent); + } catch (Throwable t) + { + memoryPercentError = true; + System.out.println("Problem calling MemoryPercent.memPercent(" + + percent + + "). Likely to be problem with com.sun.management.OperatingSystemMXBean"); + t.printStackTrace(); + } + // In the case of an error reading the percentage if physical memory, let's cap maxMemLong to 8GB + if (memoryPercentError && jvmmempc != null && pcmem == -1 + && memmax > noMemMaxHeapSizeDefault) + { + System.out.println( + "Capping maximum memory to 8GB due to failure to read physical memory size."); + memmax = noMemMaxHeapSizeDefault; + } - long physicalMem = getPhysicalMemory(); - if (physicalMem > applicationMinMemory) + if (pcmem == -1) // not set + { + maxMemLong = memmax; + } + else { - // try and set at least applicationMinMemory and thereafter ensure - // leaveFreeMinMemory is left for the OS - memPercent = Math.max(applicationMinMemory, - physicalMem - Math.max(physicalMem * (100 - percent) / 100, - leaveFreeMinMemory)); + maxMemLong = Math.min(pcmem, memmax); } - return memPercent; + return maxMemLong; } }