Statistics
| Revision:

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 @ 524

History | View | Annotate | Download (9.23 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.write(getNewLineChars());
204
                                        }
205
                                        else {
206
                                                written = true; // avoid writing the mem line twice
207
                                                writer.write(getEncodedMaxMemoryLine(maximumMemory));
208
                                                writer.write(getNewLineChars());
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
        /**
265
         * Gets the character(s) used as line separators. We don't use the "line.separator"
266
         * Java property because we currently must use the Unix-style separator even in Windows,
267
         * and this might change in the future.
268
         * @return
269
         */
270
        protected abstract String getNewLineChars();
271
        
272
        public int getFactoryDefaultMaximum() {
273
                return FACTORY_DEFAULT_MAXIMUM;
274
        }
275
}