001    package org.shiftone.jrat.core;
002    
003    import org.shiftone.jrat.core.shutdown.ShutdownListener;
004    import org.shiftone.jrat.core.spi.RuntimeContext;
005    import org.shiftone.jrat.util.io.IOUtil;
006    import org.shiftone.jrat.util.log.Logger;
007    
008    import java.io.Writer;
009    
010    /**
011     * @author jeff@shiftone.org (Jeff Drost)
012     *         TODO - add support for java.lang.management.MemoryMXBean
013     */
014    public class MemoryMonitor implements ShutdownListener {
015    
016        private static final Logger LOG = Logger.getLogger(MemoryMonitor.class);
017        private final RuntimeContext context;
018        private final Writer writer;
019        private final Thread thread;
020        private static final Runtime RT = Runtime.getRuntime();
021        private volatile boolean running = true;
022    
023    
024        public MemoryMonitor(RuntimeContext context) {
025    
026            this.context = context;
027            this.writer = context.createWriter("memory.csv");
028    
029    
030            this.thread = new Thread(new Ticker());
031            thread.setDaemon(true);
032            thread.setName("Memory Ticker");
033            thread.setPriority(Thread.NORM_PRIORITY - 1);
034            thread.start();
035    
036            context.registerShutdownListener(this);
037    
038        }
039    
040        public void shutdown() throws InterruptedException {
041            running = false;
042            thread.join(1000 * 10);
043        }
044    
045        private void header() throws Exception {
046    
047            StringBuffer sb = new StringBuffer();
048            sb.append("time ms");
049            sb.append(",");
050            sb.append("free");
051            sb.append(",");
052            sb.append("max");
053            sb.append(",");
054            sb.append("total");
055            sb.append("\n");
056    
057            writer.write(sb.toString());
058        }
059    
060        private void execute() throws Exception {
061    
062            StringBuffer sb = new StringBuffer();
063    
064            sb.append(System.currentTimeMillis() - context.getStartTimeMs());
065            sb.append(",");
066            sb.append(RT.freeMemory());
067            sb.append(",");
068            sb.append(RT.maxMemory());
069            sb.append(",");
070            sb.append(RT.totalMemory());
071            sb.append("\n");
072    
073            writer.write(sb.toString());
074            writer.flush();
075    
076        }
077    
078    
079        public String toString() {
080            return "Memory Monitor";
081        }
082    
083        private class Ticker implements Runnable {
084    
085            public void run() {
086    
087                try {
088                    header();
089                    while (running) {
090                        execute();
091                        Thread.sleep(1000);
092                    }
093                } catch (Exception e) {
094                    running = false;
095                }
096    
097                IOUtil.close(writer);
098            }
099    
100    
101        }
102    }
103