Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / iapi / services / memory / LowMemory.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/iapi/services/memory/LowMemory.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/iapi/services/memory/LowMemory.java
new file mode 100644 (file)
index 0000000..04cc136
--- /dev/null
@@ -0,0 +1,138 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.iapi.services.memory.LowMemory\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.iapi.services.memory;\r
+\r
+/**\r
+ * Methods to aid classes recover from OutOfMemoryErrors by denying\r
+ * or reducing service rather than a complete shutdown of the JVM.\r
+ * It's intended that classes use to functionality to allow then to\r
+ * deny service when memory is low to allow the JVM to recover,\r
+ * rather than start new operations that are probably doomed to\r
+ * failure due to the low memory.\r
+ * <P>\r
+ * Expected usage is one instance of this class per major logical\r
+ * operation, e.g. creating a connection, preparing a statement,\r
+ * adding an entry to a specific cache etc.\r
+ * <BR>\r
+ * The logical operation would call isLowMemory() before starting\r
+ * the operation, and thrown a static exception if it returns true.\r
+ * <BR>\r
+ * If during the operation an OutOfMemoryException is thrown the\r
+ * operation would call setLowMemory() and throw its static exception\r
+ * representing low memory.\r
+ * <P>\r
+ * Future enhancments could be a callback mechanism for modules\r
+ * where they register they can reduce memory usage on a low\r
+ * memory situation. These callbacks would be triggered by\r
+ * a call to setLowMemory. For example the page cache could\r
+ * reduce its current size by 10% in a low memory situation.\r
+ * \r
+ */\r
+public class LowMemory {\r
+\r
+    /**\r
+     * Free memory seen when caller indicated an out of\r
+     * memory situation. Becomes a low memory watermark\r
+     * for five seconds that causes isLowMemory to return\r
+     * true if free memory is lower than this value.\r
+     * This allows the JVM a chance to recover memory\r
+     * rather than start new operations that are probably\r
+     * doomed to failure due to the low memory.\r
+     * \r
+     */\r
+    private long lowMemory;\r
+    \r
+    /**\r
+     * Time in ms corresponding to System.currentTimeMillis() when\r
+     * lowMemory was set.\r
+     */\r
+    private long whenLowMemorySet;\r
+    \r
+    /**\r
+     * Set a low memory watermark where the owner of this object just hit an\r
+     * OutOfMemoryError. The caller is assumed it has just freed up any\r
+     * references it obtained during the operation, so that the freeMemory call\r
+     * as best as it can reflects the memory before the action that caused the\r
+     * OutOfMemoryError, not part way through the action.\r
+     * \r
+     */\r
+    public void setLowMemory() {\r
+        \r
+        // Can read lowMemory unsynchronized, worst\r
+        // case is that we force extra garbage collection.\r
+        if (lowMemory == 0L) {\r
+            \r
+            // The caller tried to dereference any objects it\r
+            // created during its instantation. Try to garbage\r
+            // collect these so that we can a best-guess effort\r
+            // at the free memory before the overall operation we are\r
+            // failing on occurred. Of course in active multi-threading\r
+            // systems we run the risk that some other thread just freed\r
+            // up some memory that throws off our calcuation. This is\r
+            // avoided by clearing lowMemory some time later on an\r
+            // isLowMemory() call.\r
+            for (int i = 0; i < 5; i++) {\r
+                System.gc();\r
+                System.runFinalization();\r
+                try {\r
+                    Thread.sleep(50L);\r
+                } catch (InterruptedException e) {\r
+                }\r
+            }\r
+        }\r
+        synchronized (this) {\r
+            if (lowMemory == 0L) {\r
+                lowMemory = Runtime.getRuntime().freeMemory();\r
+                whenLowMemorySet = System.currentTimeMillis();\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Return true if a low memory water mark has been set and the current free\r
+     * memory is lower than it. Otherwise return false.\r
+     */\r
+    public boolean isLowMemory() {\r
+        synchronized (this) {\r
+            long lm = lowMemory;\r
+            if (lm == 0)\r
+                return false;\r
+            \r
+            if (Runtime.getRuntime().freeMemory() > lm)\r
+                return false;\r
+            \r
+            // Only allow an low memory watermark to be valid\r
+            // for five seconds after it was set. This stops\r
+            // an incorrect limit being set for ever. This could\r
+            // occur if other threads were freeing memory when\r
+            // we called Runtime.getRuntime().freeMemory()\r
+           \r
+            long now = System.currentTimeMillis();\r
+            if ((now - this.whenLowMemorySet) > 5000L) {\r
+                lowMemory = 0L;\r
+                whenLowMemorySet = 0L;\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
+    }\r
+}\r