001 /*--------------------------------------------------------------------------+ 002 $Id: MemoryMonitor.java 26268 2010-02-18 10:44:30Z juergens $ 003 | | 004 | Copyright 2005-2010 Technische Universitaet Muenchen | 005 | | 006 | Licensed under the Apache License, Version 2.0 (the "License"); | 007 | you may not use this file except in compliance with the License. | 008 | You may obtain a copy of the License at | 009 | | 010 | http://www.apache.org/licenses/LICENSE-2.0 | 011 | | 012 | Unless required by applicable law or agreed to in writing, software | 013 | distributed under the License is distributed on an "AS IS" BASIS, | 014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 015 | See the License for the specific language governing permissions and | 016 | limitations under the License. | 017 +--------------------------------------------------------------------------*/ 018 package edu.tum.cs.commons.system; 019 020 import java.util.Timer; 021 import java.util.TimerTask; 022 023 /** 024 * A simple class for monitoring memory usage of an application. A second thread 025 * is started which periodically polls the memory status. <br/><br/> <b>Note: 026 * </b> Due to performance reasons the method 027 * <code>getMaximumMemoryUsage()</code> and <code>reset()</code> are <b>not 028 * </b> synchronized, so calling these methods while the memory monitor is still 029 * running might lead to undesired results. Therefore it is recommended stop the 030 * memory befor calling <code>getMaximumMemoryUsage()</code> or 031 * <code>reset()</code>. 032 * 033 * @author Florian Deissenboeck 034 * @author $Author: juergens $ 035 * 036 * @version $Revision: 26268 $ 037 * @levd.rating GREEN Hash: 5CEE7382009C9846609F2FA2C23D122D 038 */ 039 public class MemoryMonitor { 040 /** Default polling period [ms]. */ 041 private static final int DEFAULT_PERIOD = 50; 042 043 /** The timer for controlling the periodical call. */ 044 private Timer timer; 045 046 /** Period between polls [ms]. */ 047 private final int period; 048 049 /** The task gathering the memory information. */ 050 private final MemoryMonitorTask monitorTask; 051 052 /** 053 * Construct a new <code>MemoryMonitor</code> with the default monitoring 054 * interval. 055 * 056 */ 057 public MemoryMonitor() { 058 this(DEFAULT_PERIOD); 059 } 060 061 /** 062 * Construct a new <code>MemoryMonitor</code>. 063 * 064 * @param period 065 * time between subsequent polls to obtain memory status 066 * @see #start() 067 */ 068 public MemoryMonitor(int period) { 069 monitorTask = new MemoryMonitorTask(); 070 this.period = period; 071 072 // start as daemon thread 073 timer = new Timer(true); 074 } 075 076 /** 077 * Start the memory monitor. 078 * 079 * @see #stop() 080 */ 081 public void start() { 082 timer.schedule(monitorTask, 0, period); 083 } 084 085 /** 086 * Stop the memory monitor. Memory monitor can be restarted safely after 087 * stopping without loosing the current maximum value. 088 * 089 * @see #start() 090 * @see #reset() 091 */ 092 public void stop() { 093 timer.cancel(); 094 timer = new Timer(true); 095 } 096 097 /** 098 * Reset the maximum memory usage value. Use this method only when monitor 099 * is stopped. 100 * 101 * @see #stop() 102 */ 103 public void reset() { 104 monitorTask.reset(); 105 } 106 107 /** 108 * Obtain maximum amount of memory used since the monitor was started or 109 * reset.Use this method only when monitor is stopped. 110 * 111 * @see #stop() 112 * 113 * @return maximum memory usage [byte] 114 */ 115 public long getMaximumMemoryUsage() { 116 return monitorTask.getMaximumMemoryUsage(); 117 } 118 119 /** 120 * A simple timer task for monitor memory status. <br/><br/><b>Note: </b> 121 * Due to performance reasons the method 122 * <code>getMaximumMemoryUsage()</code> and <code>reset()</code> are 123 * <b>not </b> synchronized, so calling these methods while the memory 124 * monitor is still running might lead to undesired results. 125 */ 126 private static class MemoryMonitorTask extends TimerTask { 127 128 /** Runtime object for accessing the VM's memory status. */ 129 private final Runtime runtime; 130 131 /** Maximum amount of memory used . */ 132 private long maxMemory = 0; 133 134 /** 135 * Set up a new monitor task. 136 * 137 */ 138 public MemoryMonitorTask() { 139 runtime = Runtime.getRuntime(); 140 } 141 142 /** 143 * Retrieve currently used memory from runtime object and update maximum 144 * memory usage if necessary. 145 */ 146 @Override 147 public void run() { 148 long usedMemory = runtime.totalMemory(); 149 if (usedMemory > maxMemory) { 150 maxMemory = usedMemory; 151 } 152 } 153 154 /** 155 * Obtain maximum amount of memory used since the monitor was started or 156 * reset.Use this method only when monitor is stopped. 157 * 158 * @return maximum memory usage [byte] 159 */ 160 public long getMaximumMemoryUsage() { 161 return maxMemory; 162 } 163 164 /** 165 * Reset the maximum memory usage value. Use this method only when 166 * monitor is stopped. 167 * 168 */ 169 public void reset() { 170 maxMemory = 0; 171 } 172 173 } 174 }