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