KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mondrian > util > MemoryMonitor


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/util/MemoryMonitor.java#4 $
3 // This software is subject to the terms of the Common Public License
4 // Agreement, available at the following URL:
5 // http://www.opensource.org/licenses/cpl.html.
6 // Copyright (C) 2007-2007 Julian Hyde and others
7 // All Rights Reserved.
8 // You must accept the terms of that agreement to use this software.
9 */

10 package mondrian.util;
11
12 /**
13  * The <code>MemoryMonitor</code> interface defines the API for
14  * Mondrian's memory monitors. For Java4, the available monitors
15  * do nothing since there is no reliable way of detecting that
16  * memory is running low using such a JVM (you are welcome to
17  * try to create one, but I believe you will fail - some such candidates
18  * only make it more likely that an OutOfMemory condition will occur).
19  * For Java5 one
20  * can optionally enable a monitor which is based upon the Java5
21  * memory classes locate in java.lang.management.
22  * <p>
23  * Clients implement the <code>MemoryMonitor.Listener</code> interface and
24  * register with the <code>MemoryMonitor</code>.
25  * <p>
26  * The <code>MemoryMonitor</code> supports having multiple
27  * <code>Listener</code> clients. The clients can have the same
28  * threshold percentage or different values. The threshold percentage value
29  * is used by the <code>MemoryMonitor</code> to determine when to
30  * notify a client. It is the percentage of the total memory,
31  * 100 * free-memory / total-memory (0 $lt;= free-memory $lt;= total-memory).
32  *
33  * @author <a>Richard M. Emberson</a>
34  * @since Feb 01 2007
35  * @version $Id: //open/mondrian/src/main/mondrian/util/MemoryMonitor.java#4 $
36  */

37 public interface MemoryMonitor {
38
39     /**
40      * Adds a <code>Listener</code> to the <code>MemoryMonitor</code> with
41      * a given threshold percentage.
42      *
43      * <p>If the threshold percentage value is below the system's current
44      * value, then the * <code>Listener</code> will have its notification
45      * callback called * while in this method - so a client should
46      * always check if its notification method was called immediately
47      * after calling this method.
48      *
49      * @param listener the <code>Listener</code> being added.
50      * @param thresholdPercentage the notification threshold percentage.
51      * @return
52      */

53     boolean addListener(Listener listener, int thresholdPercentage);
54
55     /**
56      * Adds a <code>Listener</code> to the <code>MemoryMonitor</code> and
57      * uses the default threshold percentage.
58      *
59      * <p>If the default threshold percentage value is below the system's
60      * current value, then the listener's notification
61      * callback will be called while in this method - so a client should
62      * always check if its notification method was called immediately
63      * after calling this method.
64      *
65      * @param listener the <code>Listener</code> being added.
66      * @return
67      */

68     boolean addListener(final Listener listener);
69
70     /**
71      * Changes the threshold percentage of a given <code>Listener</code>.
72      *
73      * <p>If the new value is below the system's current value, then the
74      * <code>Listener</code> will have its notification callback called
75      * while in this method - so a client should always check if its
76      * notification method was called immediately after calling this
77      * method.
78      * <p>
79      * This method can be used if, for example, an algorithm has
80      * different approaches that result in different memory
81      * usage profiles; one, large memory but fast and
82      * a second which is low-memory but slow. The algorithm starts
83      * with the large memory approach, receives a low memory
84      * notification, switches to the low memory approach and changes
85      * when it should be notified for this new approach. The first
86      * approach need to be notified at a lower percentage because it
87      * uses lots of memory, possibly quickly; while the second
88      * approach, possibly a file based algorithm, has smaller memory
89      * requirements and uses memory less quickly thus one can
90      * live with a higher notification threshold percentage.
91      *
92      * @param listener
93      * @param percentage
94      */

95     void updateListenerThreshold(Listener listener, int percentage);
96
97     /**
98      * Removes a <code>Listener</code> from the <code>MemoryMonitor</code>.
99      * Returns <code>true</code> if listener was removed and
100      * <code>false</code> otherwise.
101      *
102      * @param listener the listener to be removed
103      * @return <code>true</code> if listener was removed.
104      */

105     boolean removeListener(Listener listener);
106
107     /**
108      * Clear out all <code>Listener</code>s and turnoff JVM
109      * memory notification.
110      */

111     void removeAllListener();
112
113     /**
114      * Returns the maximum memory usage.
115      *
116      * @return the maximum memory usage.
117      */

118     long getMaxMemory();
119
120     /**
121      * Returns the current memory used.
122      *
123      * @return the current memory used.
124      */

125     long getUsedMemory();
126
127
128     /**
129      * A <code>MemoryMonitor</code> client implements the <code>Listener</code>
130      * interface and registers with the <code>MemoryMonitor</code>.
131      * When the <code>MemoryMonitor</code> detects that free memory is
132      * low, it notifies the client by calling the client's
133      * <code>memoryUsageNotification</code> method. It is important
134      * that the client quickly return from this call, that the
135      * <code>memoryUsageNotification</code> method does not do a lot of
136      * work. It is best if it simply sets a flag. The flag should be
137      * polled by an application thread and when it detects that the
138      * flag was set, it should take immediate memory relinquishing operations.
139      * In the case of Mondrian, the present query is aborted.
140      */

141     interface Listener {
142
143         /**
144          * When the <code>MemoryMonitor</code> determines that the
145          * <code>Listener</code>'s threshold is equal to or less than
146          * the current available memory (post garbage collection),
147          * then this method is called with the current memory usage,
148          * <code>usedMemory</code>, and the maximum memory (which
149          * is a constant per JVM invocation).
150          * <p>
151          * This method is called (in the case of Java5) by a system
152          * thread associated with the garbage collection activity.
153          * When this method is called, the client should quickly do what
154          * it needs to to communicate with an application thread and
155          * then return. Generally, quickly de-referencing some big objects
156          * and setting a flag is the most that should be done by
157          * implementations of this method. If the implementor chooses to
158          * de-reference some objects, then the application code must
159          * be written so that if will not throw a NullPointerException
160          * when such de-referenced objects are accessed. If a flag
161          * is set, then the application must be written to check the
162          * flag periodically.
163          *
164          * @param usedMemory the current memory used.
165          * @param maxMemory the maximum available memory.
166          */

167         void memoryUsageNotification(long usedMemory, long maxMemory);
168     }
169
170     /**
171      * This is an interface that a <code>MemoryMonitor</code> may optionally
172      * implement. These methods give the tester access to some of the
173      * internal, white-box data.
174      * <p>
175      * During testing Mondrian has a default
176      * <code>MemoryMonitor</code> which might be replaced with a test
177      * <code>MemoryMonitor</code>s using the <code>ThreadLocal</code>
178      * mechanism. After the test using the test
179      * <code>MemoryMonitor</code> finishes, a call to the
180      * <code>resetFromTest</code> method allows
181      * the default <code>MemoryMonitor</code> reset itself.
182      * This is hook that should only be called as part of testing.
183      */

184     interface Test {
185
186         /**
187          * This should only be called when one is switching from a
188          * test <code>MemoryMonitor</code> back to the default system
189          * <code>MemoryMonitor</code>. In particular, look at
190          * the <code>MemoryMonitorFactory</code>'s
191          * <code>clearThreadLocalClassName()</code> method for its
192          * usage.
193          */

194         void resetFromTest();
195     }
196 }
197
198 // End MemoryMonitor.java
199
Popular Tags