gvsig-projects-pool / org.gvsig.jvmpreferences / trunk / org.gvsig.jvmpreferences.native / org.gvsig.jvmpreferences.native.lib / org.gvsig.jvmpreferences.native.lib.impl.common / src / main / java / org / gvsig / jvmpreferences / nativeprefs / BaseMemoryPreferences.java @ 6
History | View | Annotate | Download (8.92 KB)
1 |
package org.gvsig.jvmpreferences.nativeprefs; |
---|---|
2 |
|
3 |
|
4 |
import java.io.BufferedInputStream; |
5 |
import java.io.BufferedOutputStream; |
6 |
import java.io.BufferedReader; |
7 |
import java.io.BufferedWriter; |
8 |
import java.io.File; |
9 |
import java.io.FileInputStream; |
10 |
import java.io.FileNotFoundException; |
11 |
import java.io.FileOutputStream; |
12 |
import java.io.FileReader; |
13 |
import java.io.FileWriter; |
14 |
import java.io.IOException; |
15 |
import java.io.InputStream; |
16 |
import java.io.OutputStream; |
17 |
import java.lang.management.ManagementFactory; |
18 |
import java.text.SimpleDateFormat; |
19 |
import java.util.Date; |
20 |
import java.util.regex.Matcher; |
21 |
import java.util.regex.Pattern; |
22 |
|
23 |
import javax.management.AttributeNotFoundException; |
24 |
import javax.management.InstanceNotFoundException; |
25 |
import javax.management.MBeanException; |
26 |
import javax.management.MBeanServer; |
27 |
import javax.management.MalformedObjectNameException; |
28 |
import javax.management.ObjectName; |
29 |
import javax.management.ReflectionException; |
30 |
|
31 |
import org.gvsig.i18n.Messages; |
32 |
import org.gvsig.jvmpreferences.nativeprefs.MemoryPreferences; |
33 |
import org.slf4j.LoggerFactory; |
34 |
|
35 |
/**
|
36 |
* This class abstracts the complexity of reading/storing
|
37 |
* memory preferences for different operating systems
|
38 |
*
|
39 |
* @author Cesar Martinez Izquierdo
|
40 |
*
|
41 |
*/
|
42 |
public abstract class BaseMemoryPreferences implements MemoryPreferences { |
43 |
public static final int FACTORY_DEFAULT_MAXIMUM = 512; |
44 |
|
45 |
/* (non-Javadoc)
|
46 |
* @see org.gvsig.preferences.nativeprefs.general.memory.MemoryPreferences#getConfigFile()
|
47 |
*/
|
48 |
public abstract File getConfigFile(); |
49 |
|
50 |
/* (non-Javadoc)
|
51 |
* @see org.gvsig.preferences.nativeprefs.general.memory.MemoryPreferences#isConfigWritable()
|
52 |
*/
|
53 |
public boolean isConfigWritable(){ |
54 |
return getConfigFile().canWrite();
|
55 |
} |
56 |
|
57 |
/* (non-Javadoc)
|
58 |
* @see org.gvsig.preferences.nativeprefs.general.memory.MemoryPreferences#getTotalSystemMemory()
|
59 |
*/
|
60 |
public int getTotalSystemMemory() { |
61 |
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); |
62 |
Object attribute;
|
63 |
try {
|
64 |
attribute = mBeanServer.getAttribute(new ObjectName("java.lang","type","OperatingSystem"), "TotalPhysicalMemorySize"); |
65 |
System.out.println("Total memory: "+ attribute.toString() +" B"); |
66 |
System.out.println("Total memory: "+ Long.parseLong(attribute.toString())/(1024*1024) +" MB"); |
67 |
return (int) (Long.parseLong(attribute.toString())/(1024*1024)); |
68 |
} catch (AttributeNotFoundException e) { |
69 |
LoggerFactory.getLogger(BaseMemoryPreferences.class).error("Total_system_memory_cant_be_retrived", e);
|
70 |
} catch (InstanceNotFoundException e) { |
71 |
LoggerFactory.getLogger(BaseMemoryPreferences.class).error("Total_system_memory_cant_be_retrived", e);
|
72 |
} catch (MalformedObjectNameException e) { |
73 |
LoggerFactory.getLogger(BaseMemoryPreferences.class).error("Total_system_memory_cant_be_retrived", e);
|
74 |
} catch (MBeanException e) { |
75 |
LoggerFactory.getLogger(BaseMemoryPreferences.class).error("Total_system_memory_cant_be_retrived", e);
|
76 |
} catch (ReflectionException e) { |
77 |
LoggerFactory.getLogger(BaseMemoryPreferences.class).error("Total_system_memory_cant_be_retrived", e);
|
78 |
} catch (NullPointerException e) { |
79 |
LoggerFactory.getLogger(BaseMemoryPreferences.class).error("Total_system_memory_cant_be_retrived", e);
|
80 |
} |
81 |
return 512; |
82 |
} |
83 |
|
84 |
/* (non-Javadoc)
|
85 |
* @see org.gvsig.preferences.nativeprefs.general.memory.MemoryPreferences#getSafeMemoryMaximum()
|
86 |
*/
|
87 |
public int getSafeMemoryMaximum() { |
88 |
int totalMemory = getTotalSystemMemory();
|
89 |
if (totalMemory<=1024) { |
90 |
return (int)(0.6*(float)totalMemory); |
91 |
} |
92 |
String arch = System.getProperty("os.arch"); |
93 |
if ("x86".equals(arch) || "i386".equals(arch)) { |
94 |
return 1200; |
95 |
} |
96 |
return (totalMemory-768); |
97 |
} |
98 |
|
99 |
/* (non-Javadoc)
|
100 |
* @see org.gvsig.preferences.nativeprefs.general.memory.MemoryPreferences#readConfiguredMaximum()
|
101 |
*/
|
102 |
public int readConfiguredMaximum() { |
103 |
File launcherFile = getConfigFile();
|
104 |
if (launcherFile.exists()) {
|
105 |
BufferedReader reader = null; |
106 |
try {
|
107 |
reader = new BufferedReader(new FileReader(launcherFile)); |
108 |
String line;
|
109 |
Pattern pattern = Pattern.compile(getMaxMemoryRegexp()); |
110 |
while ((line = reader.readLine())!=null) { |
111 |
Matcher m = pattern.matcher(line);
|
112 |
if (m.matches()) {
|
113 |
String memoryStr=m.group(1); |
114 |
String units = m.group(2); |
115 |
int configMemory;
|
116 |
try {
|
117 |
// first of all assume it does not have units
|
118 |
configMemory = Integer.parseInt(memoryStr);
|
119 |
System.out.println("Configured memory: " + configMemory); |
120 |
if (units!=null) { |
121 |
units = units.toLowerCase(); |
122 |
if ("g".equals(units)) { |
123 |
configMemory = configMemory * 1024;
|
124 |
} |
125 |
else if ("k".equals(units)) { |
126 |
configMemory = (int)((float)configMemory/1024.0); |
127 |
} |
128 |
} |
129 |
return configMemory;
|
130 |
} |
131 |
catch (NumberFormatException ex) { |
132 |
} |
133 |
} |
134 |
} |
135 |
} catch (FileNotFoundException e) { |
136 |
LoggerFactory.getLogger(this.getClass()).error(Messages.getText("Memory_config_could_not_be_retrived"), e); |
137 |
} catch (NumberFormatException e) { |
138 |
LoggerFactory.getLogger(this.getClass()).error(Messages.getText("Memory_config_could_not_be_retrived"), e); |
139 |
} catch (IOException e) { |
140 |
LoggerFactory.getLogger(this.getClass()).error(Messages.getText("Memory_config_could_not_be_retrived"), e); |
141 |
} |
142 |
finally {
|
143 |
try {
|
144 |
if (reader!=null) { |
145 |
reader.close(); |
146 |
} |
147 |
} catch (IOException e) { |
148 |
} |
149 |
} |
150 |
} |
151 |
LoggerFactory.getLogger(this.getClass()).error(Messages.getText("Memory_config_could_not_be_retrived")); |
152 |
return getSafeMemoryMaximum();
|
153 |
} |
154 |
|
155 |
/**
|
156 |
* Copies one file. We are not using
|
157 |
* {@link org.gvsig.utils.FileUtils#copy(File, File)} method
|
158 |
* because it does not use buffered reader. Probably it should be corrected
|
159 |
* there and removed from here
|
160 |
*
|
161 |
* @param src The file to copy
|
162 |
* @param dst The destination file
|
163 |
* @throws IOException
|
164 |
*/
|
165 |
public static void copy(File src, File dst) throws IOException { |
166 |
InputStream in = new BufferedInputStream(new FileInputStream(src)); |
167 |
OutputStream out = new BufferedOutputStream(new FileOutputStream(dst)); |
168 |
|
169 |
// Transfer bytes from in to out
|
170 |
byte[] buf = new byte[10240]; |
171 |
int len;
|
172 |
while ((len = in.read(buf)) > 0) { |
173 |
out.write(buf, 0, len);
|
174 |
} |
175 |
in.close(); |
176 |
out.close(); |
177 |
} |
178 |
|
179 |
|
180 |
/* (non-Javadoc)
|
181 |
* @see org.gvsig.preferences.nativeprefs.general.memory.MemoryPreferences#saveConguredMaximum()
|
182 |
*/
|
183 |
public void saveConguredMaximum(int maximumMemory) { |
184 |
File launcherFile = getConfigFile();
|
185 |
if (launcherFile.exists()) {
|
186 |
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS"); |
187 |
String date = format.format(new Date()); |
188 |
File backupFile = new File(launcherFile.getAbsolutePath()+"-"+date+".bak"); |
189 |
|
190 |
BufferedWriter writer = null; |
191 |
BufferedReader reader = null; |
192 |
|
193 |
try {
|
194 |
copy(launcherFile, backupFile); |
195 |
writer = new BufferedWriter(new FileWriter(launcherFile)); |
196 |
reader = new BufferedReader(new FileReader(backupFile)); |
197 |
String line;
|
198 |
Pattern pattern = Pattern.compile(getMaxMemoryRegexp()); |
199 |
boolean written = false; |
200 |
while ((line = reader.readLine())!=null) { |
201 |
if (!pattern.matcher(line).matches() || written) {
|
202 |
writer.write(line); |
203 |
writer.newLine(); |
204 |
} |
205 |
else {
|
206 |
written = true; // avoid writing the mem line twice |
207 |
writer.write(getEncodedMaxMemoryLine(maximumMemory)); |
208 |
writer.newLine(); |
209 |
} |
210 |
} |
211 |
} catch (FileNotFoundException e) { |
212 |
LoggerFactory.getLogger(this.getClass()).error(Messages.getText("Memory_config_could_not_be_written"), e); |
213 |
} catch (IOException e) { |
214 |
LoggerFactory.getLogger(this.getClass()).error(Messages.getText("Memory_config_could_not_be_written"), e); |
215 |
} |
216 |
finally {
|
217 |
if (reader!=null) { |
218 |
try {
|
219 |
reader.close(); |
220 |
} catch (IOException e) { |
221 |
LoggerFactory.getLogger(this.getClass()).debug(Messages.getText("Error_closing_reader"), e); |
222 |
} |
223 |
} |
224 |
if (writer!=null) { |
225 |
try {
|
226 |
writer.close(); |
227 |
} catch (IOException e) { |
228 |
LoggerFactory.getLogger(this.getClass()).debug(Messages.getText("Error_closing_writer"), e); |
229 |
} |
230 |
} |
231 |
} |
232 |
} |
233 |
} |
234 |
|
235 |
/**
|
236 |
* A valid Java regular expression that matches the line
|
237 |
* containing the maximum memory parameter (-Xmx) parameter
|
238 |
* on the launcher file for this platform.
|
239 |
*
|
240 |
* The regular expression must contain 2 capturing groups,
|
241 |
* the first one capturing the numeric part and the second
|
242 |
* one capturing the units.
|
243 |
*
|
244 |
* E.g. for the definition -Xmx1024M,
|
245 |
* the first group must capture '1024', while the second
|
246 |
* group must capture the 'M'.
|
247 |
*
|
248 |
* Note that the units may be absent in the definition string.
|
249 |
*
|
250 |
* @return A valid Java regular expression
|
251 |
*/
|
252 |
protected abstract String getMaxMemoryRegexp(); |
253 |
|
254 |
/**
|
255 |
* Encodes the maximum memory parameter (-Xmx) in a suitable format
|
256 |
* for being directly written on the launcher configuration files
|
257 |
* for this platform.
|
258 |
*
|
259 |
* @param maximumMemory
|
260 |
* @return
|
261 |
*/
|
262 |
protected abstract String getEncodedMaxMemoryLine(int maximumMemory); |
263 |
|
264 |
public int getFactoryDefaultMaximum() { |
265 |
return FACTORY_DEFAULT_MAXIMUM;
|
266 |
} |
267 |
} |