You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by vg...@apache.org on 2007/01/25 17:38:06 UTC
svn commit: r499840 - in /cocoon/trunk/core/cocoon-store/cocoon-store-impl:
./
src/main/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java
src/main/resources/META-INF/cocoon/spring/cocoon-core-store-janitor.xml
Author: vgritsenko
Date: Thu Jan 25 08:38:05 2007
New Revision: 499840
URL: http://svn.apache.org/viewvc?view=rev&rev=499840
Log:
<action dev="VG" type="add">
Core: In store janitor, add an option to cleanup all stores on each janitor
run. Default behavior is to cleanup one store at a time.
</action>
Modified:
cocoon/trunk/core/cocoon-store/cocoon-store-impl/ (props changed)
cocoon/trunk/core/cocoon-store/cocoon-store-impl/src/main/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java
cocoon/trunk/core/cocoon-store/cocoon-store-impl/src/main/resources/META-INF/cocoon/spring/cocoon-core-store-janitor.xml
Propchange: cocoon/trunk/core/cocoon-store/cocoon-store-impl/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Thu Jan 25 08:38:05 2007
@@ -1,3 +1,4 @@
+*.iml
.project
.settings
target
Modified: cocoon/trunk/core/cocoon-store/cocoon-store-impl/src/main/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-store/cocoon-store-impl/src/main/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java?view=diff&rev=499840&r1=499839&r2=499840
==============================================================================
--- cocoon/trunk/core/cocoon-store/cocoon-store-impl/src/main/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java (original)
+++ cocoon/trunk/core/cocoon-store/cocoon-store-impl/src/main/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java Thu Jan 25 08:38:05 2007
@@ -32,23 +32,36 @@
* the StoreJanitor frees the registered caches until memory is normal.
*
* <p>A few parameters can be used:
- * <UL>
- * <LI><B>freememory</B>: How many bytes shall be always free in the JVM (Default: 1mb)</LI>
- * <LI><B>heapsize</B>: Maximum possible size of the JVM memory consumption (Default: 64mb)</LI>
- * <LI><B>cleanupthreadinterval</B>: How often (sec) shall run the cleanup thread (Default: 10s)</LI>
- * <LI><B>adaptivethreadinterval</B> (experimental): Enable adaptive algorithm to determine thread interval
+ * <ul>
+ * <li><b>freememory</b>: How many bytes shall be always free in the JVM (Default: 1mb)</li>
+ * <li><b>heapsize</b>: Maximum possible size of the JVM memory consumption (Default: 64mb)</li>
+ * <li><b>cleanupthreadinterval</b>: How often (sec) shall run the cleanup thread (Default: 10s)</li>
+ * <li><b>adaptivethreadinterval</b> (experimental): Enable adaptive algorithm to determine thread interval
* (Default: false) When true, <code>cleanupthreadinterval</code> defines the maximum cleanup interval.
* Cleanup interval then is determined based on the memory fill rate: the faster memory is filled in,
- * and the less free memory is left, the shorter is the cleanup time.</LI>
- * <LI><B>threadpriority</B>: priority of the thread (1-10). (Default: 10)</LI>
- * <LI><B>percent_to_free</B>: What fraction of the store to free when memory is low (1-100). (Default: 10%)</LI>
- * <LI><B>invokegc</B>: Invoke the gc on low memory first (true|false; default: false)</LI>
- * </UL></p>
+ * and the less free memory is left, the shorter is the cleanup time.</li>
+ * <li><b>threadpriority</b>: priority of the thread (1-10). (Default: current thread's priority)</li>
+ * <li><b>percent_to_free</b>: What fraction of the store to free when memory is low (1-100). (Default: 10%)</li>
+ * <li><b>invokegc</b>: Invoke the gc on low memory first (true|false; default: false)</li>
+ * <li><b>freeingalgorithm</b>: Currently there are two algorithms available. (Default: round-robun)
+ * <dl>
+ * <dt>round-robin</dt>
+ * <dd>The registered caches are cycled through,
+ * and each time there is a low memory situation one of the
+ * registered caches has objects freed from it.</dd>
+ * <dt>all-stores</dt>
+ * <dd>All registered stores have objects removed from them
+ * each time there is a low memory situation.</dd>
+ * </ul></p>
*
* @version $Id$
*/
public class StoreJanitorImpl implements StoreJanitor, Runnable {
+ // Cleaning Algorithms
+ private static final String ALG_ROUND_ROBIN = "round-robin";
+ private static final String ALG_ALL_STORES = "all-stores";
+
// Note: this class doesn't need to be Startable. This allows the janitor thread to be
// lazily created the first time a store registers itsefl
@@ -68,15 +81,17 @@
private int minThreadInterval = 500;
private boolean adaptiveThreadInterval = ADAPTIVE_THREAD_INTERVAL;
private int priority = -1;
+ private String freeingAlgorithm = ALG_ROUND_ROBIN;
private double fraction = PERCENT_TO_FREE / 100.0D;
+ /** Should the gc be called on low memory? */
+ protected boolean invokeGC;
+
+ // Runtime state
private Runtime jvm;
private ArrayList storelist;
private int index = -1;
- /** Should the gc be called on low memory? */
- protected boolean invokeGC = false;
-
private boolean doRun;
/**
@@ -167,6 +182,10 @@
this.priority = threadPriority;
}
+ public void setFreeingAlgorithm(String algorithm) {
+ this.freeingAlgorithm = algorithm;
+ }
+
public Log getLogger() {
return this.logger;
}
@@ -181,8 +200,9 @@
*/
public void init() throws Exception {
this.jvm = Runtime.getRuntime();
- if (this.priority == -1)
+ if (this.priority == -1) {
this.priority = Thread.currentThread().getPriority();
+ }
if (getMinFreeMemory() < 1) {
throw new Exception("StoreJanitorImpl freememory parameter has to be greater then 1");
@@ -199,6 +219,9 @@
if (fraction > 1 && fraction < 0.01) {
throw new Exception("StoreJanitorImpl percentToFree, has to be between 1 and 100");
}
+ if (!this.freeingAlgorithm.equals(ALG_ROUND_ROBIN) || !this.freeingAlgorithm.equals(ALG_ALL_STORES)) {
+ throw new Exception("StoreJanitorImpl freeingAlgorithm, has to be round-robin or all-stores.");
+ }
this.storelist = new ArrayList();
@@ -211,6 +234,7 @@
getLogger().debug("percent=" + fraction * 100);
getLogger().debug("invoke gc=" + this.invokeGC);
}
+
doStart();
}
@@ -249,6 +273,7 @@
try {
Thread.sleep(this.interval);
} catch (InterruptedException ignore) {
+ /* ignored */
}
// Ignore change in memory during the first run (startup)
@@ -400,12 +425,24 @@
}
/**
- * Round Robin alghorithm for freeing the registered caches.
+ * Free configured percentage of objects from stores
+ * based on selected algorithm.
*/
private void freeMemory() {
- // TODO: Alternative to RR might be to free same fraction from every storage.
try {
- // Determine the store.
+ // What algorithm was selected?
+
+ // Option 1: Downsize all registered stores
+ if (this.freeingAlgorithm.equals(ALG_ALL_STORES)) {
+ for (Iterator i = iterator(); i.hasNext(); ) {
+ removeStoreObjects((Store) i.next());
+ }
+
+ return;
+ }
+
+ // Option 2: Default to Round Robin
+ // Determine the store to clear this time around.
if (getIndex() < getStoreList().size()) {
if (getIndex() == -1) {
setIndex(0);
@@ -418,20 +455,9 @@
setIndex(0);
}
- // Delete proportionate elements out of the store as configured.
- Store store = (Store)getStoreList().get(getIndex());
- int limit = calcToFree(store);
- if (getLogger().isDebugEnabled()) {
- getLogger().debug("Freeing " + limit + " items from store #" + getIndex());
- }
+ // Remove the objects from this store
+ removeStoreObjects((Store) getStoreList().get(getIndex()));
- for (int i = 0; i < limit; i++) {
- try {
- store.free();
- } catch (OutOfMemoryError e) {
- getLogger().error("OutOfMemoryError in freeMemory()");
- }
- }
} catch (Exception e) {
getLogger().error("Error in freeMemory()", e);
} catch (OutOfMemoryError e) {
@@ -440,11 +466,35 @@
}
/**
- * This method claculates the number of Elements to be freememory
- * out of the Cache.
+ * This method clears the configured amount of objects from
+ * the provided store
+ *
+ * @param store the Store from which to release the objects
+ */
+ private void removeStoreObjects(Store store) {
+ // Calculate how many objects to release from the store
+ int limit = calcToFree(store);
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Freeing " + limit + " items from store " + store + " with "
+ + store.size() + " items.");
+ }
+
+ // Remove the calculated number of objects from the current store
+ for (int i = 0; i < limit; i++) {
+ try {
+ store.free();
+ } catch (OutOfMemoryError e) {
+ getLogger().error("OutOfMemoryError while releasing an object from the store.");
+ }
+ }
+ }
+
+ /**
+ * This method calculates the number of items to free
+ * from the store.
*
- * @param store the Store which was selected as victim
- * @return number of elements to be removed!
+ * @param store the Store which was selected as a victim
+ * @return number of items to be removed
*/
private int calcToFree(Store store) {
int cnt = store.size();
@@ -459,6 +509,7 @@
if (getLogger().isDebugEnabled()) {
getLogger().debug("Calculating size for store " + store + " with size " + cnt + ": " + res);
}
+
return res;
}
@@ -482,7 +533,6 @@
}
}
-
private int getMinFreeMemory() {
return this.minFreeMemory;
}
@@ -511,14 +561,14 @@
return this.storelist;
}
+ private int getIndex() {
+ return this.index;
+ }
+
private void setIndex(int _index) {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Setting index=" + _index);
}
this.index = _index;
- }
-
- private int getIndex() {
- return this.index;
}
}
Modified: cocoon/trunk/core/cocoon-store/cocoon-store-impl/src/main/resources/META-INF/cocoon/spring/cocoon-core-store-janitor.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-store/cocoon-store-impl/src/main/resources/META-INF/cocoon/spring/cocoon-core-store-janitor.xml?view=diff&rev=499840&r1=499839&r2=499840
==============================================================================
--- cocoon/trunk/core/cocoon-store/cocoon-store-impl/src/main/resources/META-INF/cocoon/spring/cocoon-core-store-janitor.xml (original)
+++ cocoon/trunk/core/cocoon-store/cocoon-store-impl/src/main/resources/META-INF/cocoon/spring/cocoon-core-store-janitor.xml Thu Jan 25 08:38:05 2007
@@ -15,16 +15,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<!-- SVN $Id$ -->
- <!-- Normally uses the org.apache.excalibur.store.impl.StoreJanitorImpl as
- the default-class but as that uses its own Thread spawning there is
- the org.apache.cocoon.components.store.impl.CocoonStoreJanitor class
- to use a daemon thread from the org.apache.cocoon.components.thread.RunnableManager
- component
- NOT: As soon as our patch has been accepted by the Excalibur community and an
- excalibur-store has been release we can switch back to the original
- org.apache.excalibur.store.impl.StoreJanitorImpl class
- -->
+
+<!-- Normally uses the org.apache.excalibur.store.impl.StoreJanitorImpl as
+ the default-class but as that uses its own Thread spawning there is
+ the org.apache.cocoon.components.store.impl.CocoonStoreJanitor class
+ to use a daemon thread from the org.apache.cocoon.components.thread.RunnableManager
+ component.
+ NOTE: As soon as our patch has been accepted by the Excalibur community and an
+ excalibur-store has been release we can switch back to the original
+ org.apache.excalibur.store.impl.StoreJanitorImpl class
+
+ $Id$
+-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
@@ -86,6 +88,16 @@
+-->
<property name="invokeGC" value="false"/>
<!--+
+ | Algorithm describing how to clean caches in low memory situations.
+ | round-robin: The registered caches are cycled through,
+ | and each time there is a low memory situation one
+ | of the registered caches has objects freed from it.
+ | all-stores: All registered stores have objects removed from
+ | them each time there is a low memory situation.
+ | If not specified, defaults to 'round-robin'.
+ +-->
+ <property name="freeingAlgorithm" value="round-robin"/>
+ <!--+
| Name of the thread pool to use.
| If not specified, defaults to 'daemon'.
+-->
@@ -101,4 +113,4 @@
<property name="runnableManager" ref="org.apache.cocoon.components.thread.RunnableManager"/>
</bean>
-</beans>
\ No newline at end of file
+</beans>