source: xssim/src/test/stress/MemoryAndTimeAnalyzer.java @ 104

Revision 104, 13.8 KB checked in by wojtekp, 13 years ago (diff)
  • Property svn:mime-type set to text/plain
Line 
1package test.stress;
2
3import java.io.BufferedReader;
4import java.io.File;
5import java.io.FileInputStream;
6import java.io.FileOutputStream;
7import java.io.IOException;
8import java.io.InputStreamReader;
9import java.lang.management.MemoryMXBean;
10import java.util.ArrayList;
11import java.util.Collections;
12import java.util.List;
13import java.util.Properties;
14import java.awt.Toolkit;
15
16import org.apache.commons.logging.Log;
17import org.apache.commons.logging.LogFactory;
18
19import simulator.GridSchedulingSimulator;
20
21/**
22 * Class responsible for performin memory and time analysis of experiments
23 * execution.
24 *
25 * @author Jarek Szymczak
26 * @version $Id$
27 */
28public class MemoryAndTimeAnalyzer {
29
30        /** The class logger. */
31        private static final Log LOGGER =
32                        LogFactory.getLog(MemoryAndTimeAnalyzer.class);
33
34        /** The properties. */
35        private static Properties properties = new Properties();
36
37        /**
38         * Variables determinig what type of memories should be meassured and should
39         * it be performed in detailed or simple way.
40         */
41        private static boolean heap, nonHeap, jvm, heapDet, nonHeapDet, jvmDet;
42
43        /**
44         * Determines if the time is meassured precisly (it's not disturb with
45         * memory meassuring).
46         */
47        private static boolean timePrec;
48
49        /** Memory details output stream. */
50        private static FileOutputStream outDetails;
51
52        /** The current number of iterations - used for progress calculation. */
53        private static int currentNumberOfIterations;
54
55        /** The total number of iterations - used for progress calculation. */
56        private static int totalNumberOfIterations;
57
58        /** Number of repeats of each experiments. */
59        private static int repeats;
60
61        /**
62         * It stores information about amount of system memory in a certain machine
63         * (in megabytes).
64         */
65        private static int memoryInMB;
66
67        /** The interval between memory checks (in miliseconds). */
68        private static int interval;
69
70        /**
71         * The object used for gathering the information about heap and non-heap
72         * memory.
73         */
74        private static MemoryMXBean memoryMXBean =
75                        java.lang.management.ManagementFactory.getMemoryMXBean();
76
77        /**
78         * The GSSIM object which is analyzed with certain experiment (for each
79         * experiment new object is created, and the old one is dereferenced and
80         * deleted (probably).
81         */
82        private static GridSchedulingSimulator gssim =
83                        new GridSchedulingSimulator();
84
85        /**
86         * Variables helpful during time and memory consumption analysis (they're
87         * not local to simplify working with the thread responsible for memory
88         * analysis and to write the details to outDetails output stream.
89         */
90        private static long timestart, hmemstart, hmemmax, nmemmax, jvmmemmax,
91                        timend;
92
93        /**
94         * Performs memory and time analysis of a single file.
95         *
96         * @param filename
97         *            experiment file path
98         * @param iteration
99         *            iteration number
100         * @return array with results: time, heap memory, non-heap memory and JVM
101         *         memory
102         * @throws InterruptedException
103         *             the interrupted exception when thread was interrupted during
104         *             sleep
105         */
106        private static double[] singleTask(String filename, int iteration)
107                        throws InterruptedException {
108                double[] result = new double[4];
109
110                Thread t = new Thread() {
111                        public void run() {
112                                long htemp, ntemp, jvmtemp;
113                                hmemmax = hmemstart;
114                                nmemmax = 0;
115                                jvmmemmax = 0;
116                                try {
117                                        while (!interrupted()) {
118
119                                                sleep(interval);
120
121                                                htemp =
122                                                                heap ? memoryMXBean.getHeapMemoryUsage()
123                                                                                .getUsed() : 0;
124                                                ntemp =
125                                                                nonHeap ? memoryMXBean.getNonHeapMemoryUsage()
126                                                                                .getUsed() : 0;
127                                                jvmtemp = jvm ? getJVMMemory() : 0;
128
129                                                if (htemp > hmemmax)
130                                                        hmemmax = htemp;
131                                                if (ntemp > nmemmax)
132                                                        nmemmax = ntemp;
133                                                if (htemp > jvmmemmax)
134                                                        jvmmemmax = jvmtemp;
135
136                                                if (heapDet)
137                                                        outDetails.write(String.format("%.3f\t",
138                                                                        (hmemmax - hmemstart) / (1024.0 * 1024.0))
139                                                                        .getBytes("UTF-8"));
140
141                                                if (nonHeapDet)
142                                                        outDetails.write(String.format("%.3f\t",
143                                                                        nmemmax / (1024.0 * 1024.0)).getBytes(
144                                                                        "UTF-8"));
145
146                                                if (jvmDet)
147                                                        outDetails.write(String.format("%.3f\t",
148                                                                        jvmmemmax / (1024.0 * 1024.0)).getBytes(
149                                                                        "UTF-8"));
150
151                                                if (heapDet || nonHeapDet || jvmDet)
152                                                        outDetails.write("\n".getBytes("UTF-8"));
153                                        }
154                                } catch (InterruptedException e) {
155                                        return;
156                                } catch (IOException e) {
157                                        // if this happens it's very bad,,, but it's totally
158                                        // unexpected - only if there's a problem with closing
159                                        // stream from ps process
160                                        throw new RuntimeException(e);
161                                }
162                        }
163                };
164
165                try {
166                        if (heapDet || nonHeapDet || jvmDet)
167                                outDetails.write(("\n\n" + filename + " (iteration: "
168                                                + Integer.toString(iteration) + ") \n\n")
169                                                .getBytes("UTF-8"));
170                        if (heapDet)
171                                outDetails.write("Hmem\t".getBytes("UTF-8"));
172                        if (nonHeapDet)
173                                outDetails.write("Nmem\t".getBytes("UTF-8"));
174                        if (jvmDet)
175                                outDetails.write("JVMmem\t".getBytes("UTF-8"));
176                        if (heapDet || nonHeapDet || jvmDet)
177                                outDetails.write("\n".getBytes("UTF-8"));
178                } catch (IOException e) {
179                        // if this happens it's very bad,,, but it's totally unexpected
180                        throw new RuntimeException(e);
181                }
182
183                LOGGER.info("Current progress in number of experiments performed: "
184                                + Integer.toString(currentNumberOfIterations)
185                                + " / "
186                                + Integer.toString(totalNumberOfIterations)
187                                + " ("
188                                + Integer.toString((currentNumberOfIterations) * 100
189                                                / totalNumberOfIterations) + "%)");
190
191                currentNumberOfIterations++;
192
193                gssim = null;
194
195                for (int i = 0; i < 5; i++) {
196                        Thread.sleep(600);
197                        System.gc();
198                }
199
200                hmemstart = memoryMXBean.getHeapMemoryUsage().getUsed();
201                gssim = new GridSchedulingSimulator();
202
203                if (heap || nonHeap || jvm)
204                        t.start();
205
206                timestart = System.currentTimeMillis();
207                gssim.run(new String[] { filename });
208                timend = System.currentTimeMillis();
209
210                if (heap || nonHeap || jvm) {
211                        t.interrupt();
212                        t.join();
213
214                        if (timePrec) {
215                                gssim = null;
216                                for (int i = 0; i < 5; i++)
217                                        System.gc();
218                                gssim = new GridSchedulingSimulator();
219
220                                timestart = System.currentTimeMillis();
221                                gssim.run(new String[] { filename });
222                                timend = System.currentTimeMillis();
223                        }
224                }
225
226                result[0] = (timend - timestart) / 1000.0;
227                result[1] = (hmemmax - hmemstart) / (1024.0 * 1024.0);
228                result[2] = nmemmax / (1024.0 * 1024.0);
229                result[3] = jvmmemmax / (1024.0 * 1024.0);
230
231                return result;
232        }
233
234        /**
235         * Repeats task number specified in variable "repeats" times
236         *
237         * @param filename
238         *            experiment filename
239         * @return the formatted line with results (content depends on
240         *         configuration)
241         * @throws InterruptedException
242         *             thrown when thread is interrupted during sleep
243         */
244        private static String repeatTask(String filename)
245                        throws InterruptedException {
246
247                double[] temp;
248
249                double tavg = 0;
250                double tstdev = 0;
251                double hmavg = 0;
252                double hmstdev = 0;
253                double nmstdev = 0;
254                double nmavg = 0;
255                double jvmmavg = 0;
256                double jvmmstdev = 0;
257
258                for (int i = 0; i < repeats; i++) {
259                        temp = singleTask(filename, i);
260                        tavg += temp[0];
261                        tstdev += temp[0] * temp[0];
262                        hmavg += temp[1];
263                        hmstdev += temp[1] * temp[1];
264                        nmavg += temp[2];
265                        nmstdev += temp[2] * temp[2];
266                        jvmmavg += temp[3];
267                        jvmmstdev += temp[3] * temp[3];
268                }
269
270                tavg /= repeats;
271                tstdev /= repeats;
272                hmavg /= repeats;
273                hmstdev /= repeats;
274                nmavg /= repeats;
275                nmstdev /= repeats;
276                jvmmavg /= repeats;
277                jvmmstdev /= repeats;
278
279                tstdev = Math.sqrt(tstdev - tavg * tavg);
280                hmstdev = Math.sqrt(hmstdev - hmavg * hmavg);
281                nmstdev = Math.sqrt(nmstdev - nmavg * nmavg);
282                jvmmstdev = Math.sqrt(jvmmstdev - jvmmavg * jvmmavg);
283
284                StringBuilder result =
285                                new StringBuilder(String.format("%.3f\t%.3f\t", tavg, tstdev));
286
287                if (heap)
288                        result.append(String.format("%.3f\t%.3f\t", hmavg, hmstdev));
289                if (nonHeap)
290                        result.append(String.format("%.3f\t%.3f\t", nmavg, nmstdev));
291                if (jvm)
292                        result.append(String.format("%.3f\t%.3f\t", jvmmavg, jvmmstdev));
293
294                return result.toString();
295        }
296
297        /**
298         * Gets the JVM memory. It works only under linux and only if the process
299         * name begins with "java" (so, for instance, it doesn't work when the
300         * application is run under Eclipse SDK). It depends on {@link #memoryInMB}
301         * variable
302         *
303         * @return amount of memory used by JVM process (in bytes)
304         * @throws IOException
305         *             Signals that an I/O exception has occurred.
306         */
307        public static Long getJVMMemory() throws IOException {
308                BufferedReader reader = null;
309                try {
310                        Process proc =
311                                        Runtime
312                                                        .getRuntime()
313                                                        .exec(
314                                                                        new String[] { "bash", "-c",
315                                                                                        "ps u --width=5 | grep java | tr -s ' ' | cut -d ' ' -f 4" });
316                        reader =
317                                        new BufferedReader(new InputStreamReader(proc
318                                                        .getInputStream()));
319
320                        String line;
321                        if (null != (line = reader.readLine())) {
322                                return Math.round(Double.parseDouble(line) / 100.0 * memoryInMB
323                                                * 1024.0 * 1024.0);
324                        }
325                        return null;
326                } catch (IOException e) {
327                        System.out.println(e.getMessage());
328                        return null;
329                } finally {
330                        if (reader != null)
331                                reader.close();
332                }
333
334        }
335
336        /**
337         * The main method. It reads the properties of analysis from file
338         * "properties/performance.properties" - this path is relative so it's
339         * important from which folder the application is run. Meaning of each
340         * property is described in the .properties file, please do not change it's
341         * content other than parameters' values
342         *
343         * @param args
344         *            the arguments of main methods are relative paths to
345         *            .properties files with experiments or directories containing
346         *            these files (it's not recursive)
347         * @throws IOException
348         *             Signals that an I/O exception has occurred.
349         * @throws InterruptedException
350         *             fall-through exception which is not possible to occur
351         */
352        public static void main(String[] args) throws IOException,
353                        InterruptedException {
354
355                LOGGER.info("Reading the properties");
356
357                properties.load(new FileInputStream(new File(
358                                "properties/performance.properties")));
359
360                int noOfBeeps =
361                                Integer.parseInt(properties.getProperty("NO_OF_BEEPS", "0"));
362
363                interval = Integer.parseInt(properties.getProperty("INTERVAL"));
364                repeats = Integer.parseInt(properties.getProperty("REPEATS"));
365                memoryInMB = Integer.parseInt(properties.getProperty("MEMORY_IN_MB"));
366
367                heap =
368                                "simple".equals(properties.getProperty("HEAP_MEMORY"))
369                                                || "details".equals(properties
370                                                                .getProperty("HEAP_MEMORY"));
371                heapDet = "details".equals(properties.getProperty("HEAP_MEMORY"));
372                nonHeap =
373                                "simple".equals(properties.getProperty("NON_HEAP_MEMORY"))
374                                                || "details".equals(properties
375                                                                .getProperty("NON_HEAP_MEMORY"));
376                nonHeapDet =
377                                "details".equals(properties.getProperty("NON_HEAP_MEMORY"));
378                jvm =
379                                "simple".equals(properties.getProperty("JVM_MEMORY"))
380                                                || "details".equals(properties
381                                                                .getProperty("JVM_MEMORY"));
382                jvmDet = "details".equals(properties.getProperty("JVM_MEMORY"));
383
384                timePrec = (!jvm && !heap && !nonHeap);
385
386                if ("precisly".equals(properties.getProperty("TIME_MEASURING")))
387                        timePrec = true;
388
389                LOGGER.info("Preparing file list to perform experiment");
390
391                List<String> records = new ArrayList<String>();
392
393                File temp;
394
395                if (args.length < 1)
396                        return;
397
398                for (int i = 0; i < args.length; i++) {
399                        if ((new File(args[i])).exists())
400                                if (args[i].endsWith(".properties"))
401                                        records.add(args[i]);
402                                else {
403                                        temp = new File(args[i]);
404                                        String[] files = temp.list();
405                                        if (files != null) {
406                                                for (String file : files) {
407                                                        if ((new File(args[i] + "/" + file).exists() && file
408                                                                        .endsWith(".properties")))
409                                                                records.add(args[i] + "/" + file);
410                                                }
411                                        }
412                                }
413                }
414
415                totalNumberOfIterations = repeats * records.size();
416
417                if (records.size() == 0)
418                        return;
419
420                int counter = 0;
421                File file = null;
422                File fileDetails = null;
423
424                do {
425                        counter++;
426                        file =
427                                        new File("performance_result_" + Integer.toString(counter)
428                                                        + ".txt");
429                        fileDetails =
430                                        new File("performance_result_" + Integer.toString(counter)
431                                                        + "_details.txt");
432                } while (file.exists() || fileDetails.exists());
433
434                FileOutputStream out = new FileOutputStream(file);
435
436                if (heapDet || nonHeapDet || jvmDet)
437                        outDetails = new FileOutputStream(fileDetails);
438
439                StringBuilder header = new StringBuilder("Measuring time precisly: ");
440
441                if (timePrec)
442                        header.append("yes\n");
443                else
444                        header.append("no\n");
445
446                header.append(String.format("Number of repets: %d\n", repeats));
447                header.append(String.format(
448                                "Interval between memory checking: %d ms\n", interval));
449                header.append(String.format("System memory: %d MB\n\n", memoryInMB));
450
451                header.append("Name\tTavg\tTstdev\t");
452
453                if (heap)
454                        header.append("HMavg\tHMstdev\t");
455                if (nonHeap)
456                        header.append("NMavg\tNMstdev\t");
457                if (jvm)
458                        header.append("JVMMavg\tJVMMstdev\t");
459                header.append('\n');
460
461                LOGGER.info("Measuring of performance begun");
462
463                try {
464
465                        out.write(header.toString().getBytes("UTF-8"));
466                        if (heapDet || nonHeapDet || jvmDet)
467                                outDetails
468                                                .write(("Detailed analysis of memory usage with interval: "
469                                                                + interval + "ms\n\n").getBytes("UTF-8"));
470                        Collections.sort(records);
471                        for (String record : records) {
472                                out.write((record + "\t" + repeatTask(record) + "\n")
473                                                .getBytes("UTF-8"));
474                        }
475                } finally {
476                        if (out != null)
477                                out.close();
478                        if (outDetails != null)
479                                outDetails.close();
480                }
481
482                LOGGER.info("Measuring of performance ended succesfully");
483
484                for (int i = 0; i < noOfBeeps; i++) {
485                        Toolkit.getDefaultToolkit().beep();
486                        Thread.sleep(1000);
487                }
488        }
489
490}
Note: See TracBrowser for help on using the repository browser.