JAL-3210 removing overly complicated logging. Settling for System.out.println and...
[jalview.git] / src / jalview / bin / MemorySetting.java
1 package jalview.bin;
2
3 public class MemorySetting
4 {
5   public static final long leaveFreeMinMemory = 536870912; // 0.5 GB
6
7   public static final long applicationMinMemory = 536870912; // 0.5 GB
8
9   private final static int maxHeapSizePerCentDefault = 90;
10
11   public final static String maxHeapSizePerCentProperty = "jvmmempc";
12
13   private final static long maxHeapSizeDefault = 34359738368L; // 32GB
14
15   private final static long noMemMaxHeapSizeDefault = 8589934592L; // 8GB
16
17   public final static String maxHeapSizeProperty = "jvmmemmax";
18
19   protected static boolean logToClassChecked = false;
20
21   public static long getMemorySetting()
22   {
23     return getMemorySetting(null, null);
24   }
25
26   public static long getMemorySetting(String jvmmemmaxString,
27           String jvmmempcString)
28   {
29     // actual Xmx value-to-be
30     long maxMemLong = -1;
31
32     // get (absolute) jvmmaxmem setting
33     long memmax = maxHeapSizeDefault;
34     String jvmmemmaxorig = jvmmemmaxString;
35     if (jvmmemmaxorig == null)
36     {
37       jvmmemmaxorig = System.getProperty(maxHeapSizeProperty);
38     }
39     String jvmmemmax = jvmmemmaxorig;
40     if (jvmmemmax != null && jvmmemmax.length() > 0)
41     {
42       long multiplier = 1;
43       switch (jvmmemmax.toLowerCase().substring(jvmmemmax.length() - 1))
44       {
45       case "t":
46         multiplier = 1099511627776L; // 2^40
47         jvmmemmax = jvmmemmax.substring(0, jvmmemmax.length() - 1);
48         break;
49       case "g":
50         multiplier = 1073741824; // 2^30
51         jvmmemmax = jvmmemmax.substring(0, jvmmemmax.length() - 1);
52         break;
53       case "m":
54         multiplier = 1048576; // 2^20
55         jvmmemmax = jvmmemmax.substring(0, jvmmemmax.length() - 1);
56         break;
57       case "k":
58         multiplier = 1024; // 2^10
59         jvmmemmax = jvmmemmax.substring(0, jvmmemmax.length() - 1);
60         break;
61       case "b":
62         multiplier = 1; // 2^0
63         jvmmemmax = jvmmemmax.substring(0, jvmmemmax.length() - 1);
64         break;
65       default:
66         break;
67       }
68
69       // parse the arg
70       try
71       {
72         memmax = Long.parseLong(jvmmemmax);
73       } catch (NumberFormatException e)
74       {
75         memmax = maxHeapSizeDefault;
76         System.out.println("MemorySetting Property '"
77                 + maxHeapSizeProperty
78                 + "' ("
79                 + jvmmemmaxorig + "') badly formatted, using default ("
80                 + memmax + ").");
81       }
82
83       // apply multiplier if not too big (i.e. bigger than a long)
84       if (Long.MAX_VALUE / memmax < multiplier)
85       {
86         memmax = maxHeapSizeDefault;
87         System.out.println(
88                 "MemorySetting Property '" + maxHeapSizeProperty + "' ("
89                         + jvmmemmaxorig
90                         + ") too big, using default (" + memmax + ").");
91       }
92       else
93       {
94         memmax = multiplier * memmax;
95       }
96
97       // check at least minimum value (this accounts for negatives too)
98       if (memmax < MemorySetting.applicationMinMemory)
99       {
100         memmax = MemorySetting.applicationMinMemory;
101         System.out.println(
102                 "MemorySetting Property '" + maxHeapSizeProperty + "' ("
103                         + jvmmemmaxorig
104                         + ") too small, using minimum (" + memmax + ").");
105       }
106
107     }
108     else
109     {
110       // no need to warn if no setting
111       // System.out.println("MemorySetting Property '" + maxHeapSizeProperty
112       // + "' not
113       // set.");
114     }
115
116     // get max percent of physical memory
117     float percent = maxHeapSizePerCentDefault;
118     String jvmmempc = jvmmempcString;
119     if (jvmmempc == null)
120     {
121       jvmmempc = System.getProperty(maxHeapSizePerCentProperty);
122     }
123     long pcmem = -1;
124     try
125     {
126       if (jvmmempc != null)
127       {
128         float trypercent = Float.parseFloat(jvmmempc);
129         if (0 < trypercent && trypercent <= 100f)
130         {
131           percent = trypercent;
132         }
133         else
134         {
135           System.out.println(
136                   "MemorySetting Property '" + maxHeapSizePerCentProperty
137                   + "' should be in range 1..100");
138         }
139       }
140     } catch (NumberFormatException e)
141     {
142       System.out.println(
143               "MemorySetting property '" + maxHeapSizePerCentProperty
144                       + "' (" + jvmmempc + ") badly formatted");
145     }
146
147     // catch everything in case of no com.sun.management.OperatingSystemMXBean
148     boolean memoryPercentError = false;
149     try
150     {
151       pcmem = MemoryPercent.memPercentAmount(percent);
152     } catch (Throwable t)
153     {
154       memoryPercentError = true;
155       System.out.println("Problem calling MemoryPercent.memPercent("
156               + percent
157               + "). Likely to be problem with com.sun.management.OperatingSystemMXBean");
158       t.printStackTrace();
159     }
160     // In the case of an error reading the percentage of physical memory (when jvmmempc was set), let's cap maxMemLong to 8GB
161     if (memoryPercentError && jvmmempc != null && pcmem == -1
162             && memmax > noMemMaxHeapSizeDefault)
163     {
164       System.out.println(
165               "Capping maximum memory to 8GB due to failure to read physical memory size.");
166       memmax = noMemMaxHeapSizeDefault;
167     }
168
169     if (pcmem == -1) // not set
170     {
171       maxMemLong = memmax;
172     }
173     else
174     {
175       maxMemLong = Math.min(pcmem, memmax);
176     }
177
178     return maxMemLong;
179   }
180
181 }