KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > services > memory > LowMemory


1 /*
2
3    Derby - Class org.apache.derby.iapi.services.memory.LowMemory
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.iapi.services.memory;
23
24 /**
25  * Methods to aid classes recover from OutOfMemoryErrors by denying
26  * or reducing service rather than a complete shutdown of the JVM.
27  * It's intended that classes use to functionality to allow then to
28  * deny service when memory is low to allow the JVM to recover,
29  * rather than start new operations that are probably doomed to
30  * failure due to the low memory.
31  * <P>
32  * Expected usage is one instance of this class per major logical
33  * operation, e.g. creating a connection, preparing a statement,
34  * adding an entry to a specific cache etc.
35  * <BR>
36  * The logical operation would call isLowMemory() before starting
37  * the operation, and thrown a static exception if it returns true.
38  * <BR>
39  * If during the operation an OutOfMemoryException is thrown the
40  * operation would call setLowMemory() and throw its static exception
41  * representing low memory.
42  * <P>
43  * Future enhancments could be a callback mechanism for modules
44  * where they register they can reduce memory usage on a low
45  * memory situation. These callbacks would be triggered by
46  * a call to setLowMemory. For example the page cache could
47  * reduce its current size by 10% in a low memory situation.
48  *
49  */

50 public class LowMemory {
51
52     /**
53      * Free memory seen when caller indicated an out of
54      * memory situation. Becomes a low memory watermark
55      * for five seconds that causes isLowMemory to return
56      * true if free memory is lower than this value.
57      * This allows the JVM a chance to recover memory
58      * rather than start new operations that are probably
59      * doomed to failure due to the low memory.
60      *
61      */

62     private long lowMemory;
63     
64     /**
65      * Time in ms corresponding to System.currentTimeMillis() when
66      * lowMemory was set.
67      */

68     private long whenLowMemorySet;
69     
70     /**
71      * Set a low memory watermark where the owner of this object just hit an
72      * OutOfMemoryError. The caller is assumed it has just freed up any
73      * references it obtained during the operation, so that the freeMemory call
74      * as best as it can reflects the memory before the action that caused the
75      * OutOfMemoryError, not part way through the action.
76      *
77      */

78     public void setLowMemory() {
79         
80         // Can read lowMemory unsynchronized, worst
81
// case is that we force extra garbage collection.
82
if (lowMemory == 0L) {
83             
84             // The caller tried to dereference any objects it
85
// created during its instantation. Try to garbage
86
// collect these so that we can a best-guess effort
87
// at the free memory before the overall operation we are
88
// failing on occurred. Of course in active multi-threading
89
// systems we run the risk that some other thread just freed
90
// up some memory that throws off our calcuation. This is
91
// avoided by clearing lowMemory some time later on an
92
// isLowMemory() call.
93
for (int i = 0; i < 5; i++) {
94                 System.gc();
95                 System.runFinalization();
96                 try {
97                     Thread.sleep(50L);
98                 } catch (InterruptedException JavaDoc e) {
99                 }
100             }
101         }
102         synchronized (this) {
103             if (lowMemory == 0L) {
104                 lowMemory = Runtime.getRuntime().freeMemory();
105                 whenLowMemorySet = System.currentTimeMillis();
106             }
107         }
108     }
109
110     /**
111      * Return true if a low memory water mark has been set and the current free
112      * memory is lower than it. Otherwise return false.
113      */

114     public boolean isLowMemory() {
115         synchronized (this) {
116             long lm = lowMemory;
117             if (lm == 0)
118                 return false;
119             
120             if (Runtime.getRuntime().freeMemory() > lm)
121                 return false;
122             
123             // Only allow an low memory watermark to be valid
124
// for five seconds after it was set. This stops
125
// an incorrect limit being set for ever. This could
126
// occur if other threads were freeing memory when
127
// we called Runtime.getRuntime().freeMemory()
128

129             long now = System.currentTimeMillis();
130             if ((now - this.whenLowMemorySet) > 5000L) {
131                 lowMemory = 0L;
132                 whenLowMemorySet = 0L;
133                 return false;
134             }
135             return true;
136         }
137     }
138 }
139
Popular Tags