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 }