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 2005/03/09 21:40:00 UTC
svn commit: r156680 -
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java
Author: vgritsenko
Date: Wed Mar 9 12:39:57 2005
New Revision: 156680
URL: http://svn.apache.org/viewcvs?view=rev&rev=156680
Log:
cleanups
Modified:
cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java
Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java?view=diff&r1=156679&r2=156680
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/store/impl/StoreJanitorImpl.java Wed Mar 9 12:39:57 2005
@@ -1,16 +1,16 @@
-/*
+/*
* Copyright 2002-2004 The Apache Software Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
+ * You may obtain a copy of the License at
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied.
- *
+ *
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@@ -32,7 +32,21 @@
* This class is a implentation of a StoreJanitor. Store classes
* can register to the StoreJanitor. When memory is too low,
* 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
+ * (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>
+ *
* @avalon.component
* @avalon.service type=StoreJanitor
* @x-avalon.info name=store-janitor
@@ -41,120 +55,91 @@
* @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
* @version CVS $Id: StoreJanitorImpl.java,v 1.4 2004/02/28 11:47:31 cziegeler Exp $
*/
-public class StoreJanitorImpl
-extends AbstractLogEnabled
-implements StoreJanitor,
- Parameterizable,
- ThreadSafe,
- Runnable,
- Startable
-{
-
- private boolean doRun = false;
+public class StoreJanitorImpl extends AbstractLogEnabled
+ implements StoreJanitor, Parameterizable, ThreadSafe,
+ Runnable, Startable {
// Configuration parameters
private int minFreeMemory = -1;
private int maxHeapSize = -1;
private int threadInterval = -1;
private int minThreadInterval = 500;
- private boolean adaptiveThreadInterval = false;
+ private boolean adaptiveThreadInterval;
private int priority = -1;
private double fraction;
private Runtime jvm;
private ArrayList storelist;
private int index = -1;
+
/** Should the gc be called on low memory? */
- protected boolean invokeGC = false;
- /**
- * Amount of memory in use before sleep(). Must be initially set a resonable
+ protected boolean invokeGC;
+
+ private boolean doRun;
+
+ /**
+ * Amount of memory in use before sleep(). Must be initially set a resonable
* value; ie. <code>memoryInUse()</code>
*/
protected long inUse;
+
private boolean firstRun = true;
- /** The calculated delay for the next checker run */
- protected long interval = Long.MAX_VALUE; // Sleep time in ms
- private long maxRateOfChange = 1; // Used memory change rate in bytes per second
+
+ /** The calculated delay for the next checker run in ms */
+ protected long interval = Long.MAX_VALUE;
+
+ /** Used memory change rate in bytes per second */
+ private long maxRateOfChange = 1;
+
/**
- * Initialize the StoreJanitorImpl.
- * A few options 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
- * (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>
- *
- * @param params the Configuration of the application
- * @exception ParameterException
+ * Parameterize the StoreJanitorImpl.
*/
- public void parameterize(Parameters params) throws ParameterException
- {
- if (getLogger().isDebugEnabled())
- {
- getLogger().debug("Configure StoreJanitorImpl");
- }
- setJVM(Runtime.getRuntime());
-
- setMinFreeMemory(params.getParameterAsInteger("freememory", 1024 * 1024));
- setMaxHeapSize(params.getParameterAsInteger("heapsize", 60 * 1024 * 1024));
+ public void parameterize(Parameters params) throws ParameterException {
+ this.jvm = Runtime.getRuntime();
+ this.minFreeMemory = params.getParameterAsInteger("freememory", 1024 * 1024);
+ this.maxHeapSize = params.getParameterAsInteger("heapsize", 60 * 1024 * 1024);
// Parameter value is in seconds, converted to millis
- setThreadInterval(params.getParameterAsInteger("cleanupthreadinterval", 10) * 1000);
- setAdaptiveThreadInterval(params.getParameterAsBoolean("adaptivethreadinterval", false));
- setPriority(params.getParameterAsInteger("threadpriority",
- Thread.currentThread().getPriority()));
+ this.threadInterval = params.getParameterAsInteger("cleanupthreadinterval", 10) * 1000;
+ this.adaptiveThreadInterval = params.getParameterAsBoolean("adaptivethreadinterval", false);
+ this.priority = params.getParameterAsInteger("threadpriority", Thread.currentThread().getPriority());
int percent = params.getParameterAsInteger("percent_to_free", 10);
this.invokeGC = params.getParameterAsBoolean("invokegc", this.invokeGC);
-
- if (getMinFreeMemory() < 1)
- {
+
+ if (getMinFreeMemory() < 1) {
throw new ParameterException("StoreJanitorImpl freememory parameter has to be greater then 1");
}
- if (getMaxHeapSize() < 1)
- {
+ if (getMaxHeapSize() < 1) {
throw new ParameterException("StoreJanitorImpl heapsize parameter has to be greater then 1");
}
- if (getThreadInterval() < 1)
- {
+ if (getThreadInterval() < 1) {
throw new ParameterException("StoreJanitorImpl cleanupthreadinterval parameter has to be greater then 1");
}
- if (getPriority() < 1 || getPriority() > 10)
- {
+ if (getPriority() < 1 || getPriority() > 10) {
throw new ParameterException("StoreJanitorImpl threadpriority has to be between 1 and 10");
}
- if (percent > 100 && percent < 1)
- {
+ if (percent > 100 && percent < 1) {
throw new ParameterException("StoreJanitorImpl percent_to_free, has to be between 1 and 100");
}
this.fraction = percent / 100.0D;
- setStoreList(new ArrayList());
-
- if ( getLogger().isDebugEnabled() )
- {
- getLogger().debug("minimum free memory=" + this.getMinFreeMemory());
- getLogger().debug("heapsize=" + this.getMaxHeapSize());
- getLogger().debug("thread interval=" + this.getThreadInterval());
- getLogger().debug("adaptivethreadinterval=" + this.getAdaptiveThreadInterval());
- getLogger().debug("priority=" + this.getPriority());
+ this.storelist = new ArrayList();
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("minimum free memory=" + getMinFreeMemory());
+ getLogger().debug("heapsize=" + getMaxHeapSize());
+ getLogger().debug("thread interval=" + getThreadInterval());
+ getLogger().debug("adaptivethreadinterval=" + getAdaptiveThreadInterval());
+ getLogger().debug("priority=" + getPriority());
getLogger().debug("percent=" + percent);
getLogger().debug("invoke gc=" + this.invokeGC);
}
}
- public void start()
- {
- doRun = true;
+ public void start() throws Exception {
+ this.doRun = true;
Thread checker = new Thread(this);
- if (getLogger().isDebugEnabled())
- {
+ if (getLogger().isDebugEnabled()) {
getLogger().debug("Intializing checker thread");
}
checker.setPriority(getPriority());
@@ -163,36 +148,31 @@
checker.start();
}
- public void stop()
- {
- doRun = false;
+ public void stop() {
+ this.doRun = false;
}
/**
* The "checker" thread loop.
*/
- public void run()
- {
- inUse = memoryInUse();
- while (doRun) {
+ public void run() {
+ this.inUse = memoryInUse();
+ while (this.doRun) {
checkMemory();
// Sleep
- if (getLogger().isDebugEnabled())
- {
- getLogger().debug("Sleeping for " + interval + "ms");
- }
- try
- {
- Thread.sleep(interval);
- }
- catch (InterruptedException ignore) {}
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Sleeping for " + this.interval + "ms");
+ }
+ try {
+ Thread.sleep(this.interval);
+ } catch (InterruptedException ignore) {
+ }
// Ignore change in memory during the first run (startup)
- if (firstRun)
- {
- firstRun = false;
- inUse = memoryInUse();
+ if (this.firstRun) {
+ this.firstRun = false;
+ this.inUse = memoryInUse();
}
}
}
@@ -200,15 +180,12 @@
/**
* The "checker" thread checks if memory is running low in the jvm.
*/
- protected void checkMemory()
- {
- if (getAdaptiveThreadInterval())
- {
+ protected void checkMemory() {
+ if (getAdaptiveThreadInterval()) {
// Monitor the rate of change of heap in use.
long change = memoryInUse() - inUse;
long rateOfChange = longDiv(change * 1000, interval); // bps.
- if (maxRateOfChange < rateOfChange)
- {
+ if (maxRateOfChange < rateOfChange) {
maxRateOfChange = (maxRateOfChange + rateOfChange) / 2;
}
if (getLogger().isDebugEnabled()) {
@@ -219,68 +196,53 @@
}
// Amount of memory used is greater than heapsize
- if (memoryLow())
- {
- if ( this.invokeGC )
- {
- this.freePhysicalMemory();
+ if (memoryLow()) {
+ if (this.invokeGC) {
+ freePhysicalMemory();
}
- synchronized (this)
- {
+ synchronized (this) {
if (!this.invokeGC
- || (memoryLow() && getStoreList().size() > 0))
- {
-
+ || (memoryLow() && getStoreList().size() > 0)) {
+
freeMemory();
setIndex(getIndex() + 1);
}
}
}
- if (getAdaptiveThreadInterval())
- {
+ if (getAdaptiveThreadInterval()) {
// Calculate sleep interval based on the change rate and free memory left
interval = minTimeToFill(maxRateOfChange) * 1000 / 2;
- if (interval > this.threadInterval)
- {
+ if (interval > this.threadInterval) {
interval = this.threadInterval;
- }
- else if (interval < this.minThreadInterval)
- {
+ } else if (interval < this.minThreadInterval) {
interval = this.minThreadInterval;
}
inUse = memoryInUse();
- }
- else
- {
+ } else {
interval = this.threadInterval;
}
}
+
/**
* Method to check if memory is running low in the JVM.
*
* @return true if memory is low
*/
- private boolean memoryLow()
- {
- if (getLogger().isDebugEnabled())
- {
+ private boolean memoryLow() {
+ if (getLogger().isDebugEnabled()) {
getLogger().debug("JVM Memory total: " + getJVM().totalMemory()
+ ", free: " + getJVM().freeMemory());
}
if ((getJVM().totalMemory() >= getMaxHeapSize())
- && (getJVM().freeMemory() < getMinFreeMemory()))
- {
- if (getLogger().isDebugEnabled())
- {
+ && (getJVM().freeMemory() < getMinFreeMemory())) {
+ if (getLogger().isDebugEnabled()) {
getLogger().debug("Memory is low!");
}
return true;
- }
- else
- {
+ } else {
return false;
}
}
@@ -290,8 +252,7 @@
*
* @return memory in use.
*/
- protected long memoryInUse()
- {
+ protected long memoryInUse() {
return jvm.totalMemory() - jvm.freeMemory();
}
@@ -302,19 +263,14 @@
* @param rate memory fill rate in time per bytes
* @return amount of time to fill all the memory with given fill rate
*/
- private long minTimeToFill(long rate)
- {
+ private long minTimeToFill(long rate) {
return longDiv(jvm.freeMemory(), rate);
}
- private long longDiv(long top, long bottom)
- {
- try
- {
+ private long longDiv(long top, long bottom) {
+ try {
return top / bottom;
- }
- catch (Exception e)
- {
+ } catch (Exception e) {
return top > 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
}
}
@@ -324,11 +280,9 @@
*
* @param store the store to be registered
*/
- public synchronized void register(Store store)
- {
+ public synchronized void register(Store store) {
getStoreList().add(store);
- if (getLogger().isDebugEnabled())
- {
+ if (getLogger().isDebugEnabled()) {
getLogger().debug("Registered store instance " + store + ". Stores now: "
+ getStoreList().size());
}
@@ -339,11 +293,9 @@
*
* @param store the store to be unregistered
*/
- public synchronized void unregister(Store store)
- {
+ public synchronized void unregister(Store store) {
getStoreList().remove(store);
- if (getLogger().isDebugEnabled())
- {
+ if (getLogger().isDebugEnabled()) {
getLogger().debug("Unregistered store instance " + store + ". Stores now: "
+ getStoreList().size());
}
@@ -361,32 +313,24 @@
*
* @return a java.util.Iterator
*/
- public Iterator iterator()
- {
+ public Iterator iterator() {
return getStoreList().iterator();
}
/**
* Round Robin alghorithm for freeing the registered caches.
*/
- private void freeMemory()
- {
+ private void freeMemory() {
// TODO: Alternative to RR might be to free same fraction from every storage.
- try
- {
+ try {
// Determine the store.
- if (getIndex() < getStoreList().size())
- {
- if (getIndex() == -1)
- {
+ if (getIndex() < getStoreList().size()) {
+ if (getIndex() == -1) {
setIndex(0);
}
- }
- else
- {
+ } else {
// Store list changed (one or more store has been removed).
- if (getLogger().isDebugEnabled())
- {
+ if (getLogger().isDebugEnabled()) {
getLogger().debug("Restarting from the beginning");
}
setIndex(0);
@@ -395,28 +339,20 @@
// 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 N " + getIndex());
- }
- for (int i=0; i < limit; i++)
- {
- try
- {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Freeing " + limit + " items from store #" + getIndex());
+ }
+
+ for (int i = 0; i < limit; i++) {
+ try {
store.free();
- }
- catch (OutOfMemoryError e)
- {
+ } catch (OutOfMemoryError e) {
getLogger().error("OutOfMemoryError in freeMemory()");
}
}
- }
- catch (Exception e)
- {
+ } catch (Exception e) {
getLogger().error("Error in freeMemory()", e);
- }
- catch (OutOfMemoryError e)
- {
+ } catch (OutOfMemoryError e) {
getLogger().error("OutOfMemoryError in freeMemory()");
}
}
@@ -428,21 +364,18 @@
* @param store the Store which was selected as victim
* @return number of elements to be removed!
*/
- private int calcToFree(Store store)
- {
+ private int calcToFree(Store store) {
int cnt = store.size();
- if (cnt < 0)
- {
- if ( getLogger().isDebugEnabled() )
- {
+ if (cnt < 0) {
+ if (getLogger().isDebugEnabled()) {
getLogger().debug("Unknown size of the store: " + store);
}
return 0;
}
- final int res = (int)(cnt * fraction);
- if ( getLogger().isDebugEnabled() )
- {
- getLogger().debug("Calculating size for store " + store + " with size " + cnt + " : " + res);
+
+ final int res = (int) (cnt * fraction);
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Calculating size for store " + store + " with size " + cnt + ": " + res);
}
return res;
}
@@ -450,11 +383,9 @@
/**
* This method forces the garbage collector
*/
- private void freePhysicalMemory()
- {
- if (getLogger().isDebugEnabled())
- {
- getLogger().debug("Invoking garbage collection. Memory total: "
+ private void freePhysicalMemory() {
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("Invoking GC. Memory total: "
+ getJVM().totalMemory() + ", free: "
+ getJVM().freeMemory());
}
@@ -462,96 +393,50 @@
getJVM().runFinalization();
getJVM().gc();
- if (getLogger().isDebugEnabled())
- {
- getLogger().debug("Garbage collection complete. Memory total: "
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("GC complete. Memory total: "
+ getJVM().totalMemory() + ", free: "
+ getJVM().freeMemory());
}
}
-
- private int getMinFreeMemory()
- {
- return this.minFreeMemory;
- }
- private void setMinFreeMemory(int _freememory)
- {
- this.minFreeMemory = _freememory;
+ private int getMinFreeMemory() {
+ return this.minFreeMemory;
}
- private int getMaxHeapSize()
- {
+ private int getMaxHeapSize() {
return this.maxHeapSize;
}
- private void setMaxHeapSize(int _heapsize)
- {
- this.maxHeapSize = _heapsize;
- }
-
- private int getPriority()
- {
+ private int getPriority() {
return this.priority;
}
- private void setPriority(int _priority)
- {
- this.priority = _priority;
- }
-
- private int getThreadInterval()
- {
+ private int getThreadInterval() {
return this.threadInterval;
}
- private void setThreadInterval(int _threadInterval)
- {
- this.threadInterval = _threadInterval;
- }
-
- private boolean getAdaptiveThreadInterval()
- {
+ private boolean getAdaptiveThreadInterval() {
return this.adaptiveThreadInterval;
}
- private void setAdaptiveThreadInterval(boolean _adaptiveThreadInterval)
- {
- this.adaptiveThreadInterval = _adaptiveThreadInterval;
- }
-
- private Runtime getJVM()
- {
+ private Runtime getJVM() {
return this.jvm;
}
- private void setJVM(Runtime _jvm)
- {
- this.jvm = _jvm;
- }
-
- private ArrayList getStoreList()
- {
+ private ArrayList getStoreList() {
return this.storelist;
}
- private void setStoreList(ArrayList _storelist)
- {
- this.storelist = _storelist;
- }
-
- private void setIndex(int _index)
- {
- if (getLogger().isDebugEnabled())
- {
+ private void setIndex(int _index) {
+ if (getLogger().isDebugEnabled()) {
getLogger().debug("Setting index=" + _index);
}
this.index = _index;
}
- private int getIndex()
- {
+ private int getIndex() {
return this.index;
}
}