You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jcs-users@jakarta.apache.org by Owen Wallace <OW...@euro.banta.com> on 2005/10/27 17:08:53 UTC
Memory Issues with JCS [java.lang.OutOfMemoryError: Java heap space]
Hi,
I'm having an issue with the my heap space. it looks like a memory leak,
We testing our app which uses JCS as it caching mechanism and it was fine, how ever after about 10 hours running in production we get a 'java.lang.OutOfMemoryError: Java heap space'. This is repeatable but @ different time intervals.
I upgraded to jcs 1.2.6.8 (we were using 1.2.6.5) and we have the same issue.
While reading around I found a claim on the ehcache site that it could reproduce this in a test. So I took them up on it and converted their test to run against JCS and I got a 'java.lang.OutOfMemoryError: Java heap space'.
Below I have pasted in the code of my test. I know it is a bit exteme but it does prove a point.
Has anybody else come across this problem, and if so what are my options here, is there something that I could change in my config to stop this. or is it just go into the code a find why the heap cannot clear itself through garbage collection.
I have also pasted the content of my cache.ccf at the end of the email.
Any help would be greatly appreciated.
Owen
##########################################################################
package com.bgt;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jcs.JCS;
import org.apache.jcs.engine.stats.behavior.IStatElement;
import org.apache.jcs.engine.stats.behavior.IStats;
public class JCSTest extends TestCase {
private static final Log LOG = LogFactory.getLog(JCSTest.class.getName());
protected JCS jcs;
public static void main(String[] args) {
junit.textui.TestRunner.run(JCSTest.class);
}
public JCSTest(String arg0) {
super(arg0);
}
protected void setUp() throws Exception {
super.setUp();
JCS.setConfigFilename("/cache.ccf");
jcs = JCS.getInstance("testcache");
}
protected void tearDown() throws Exception {
super.tearDown();
jcs.clear();
jcs.dispose();
}
/**
* Tests adding an entry.
*/
public void testPut() throws Exception {
final String value = "value";
final String key = "key";
// Make sure the element is not found
assertEquals(0, getListSize());
assertNull(jcs.get(key));
jcs.put(key, value);
// Get the element
LOG.info("jcs.getStats(): " + jcs.getStatistics());
assertEquals(1, getListSize());
assertNotNull(jcs.get(key));
assertEquals(value, jcs.get(key));
}
/**
* Test elements can be removed from the store
*/
public void testRemove() throws Exception {
jcs.put("key1", "value1");
assertEquals(1, getListSize());
jcs.remove("key1");
assertEquals(0, getListSize());
jcs.put("key2", "value2");
jcs.put("key3", "value3");
assertEquals(2, getListSize());
jcs.remove("key2");
assertEquals(1, getListSize());
// Try to remove an object that is not there in the store
jcs.remove("key4");
assertEquals(1, getListSize());
}
public void testMemortLeak() throws Exception {
long differenceMemoryCache = thrashCache();
LOG.info("Memory Difference is: " + differenceMemoryCache);
assertTrue(differenceMemoryCache < 500000);
}
protected long thrashCache() throws Exception {
long startingSize = measureMemoryUse();
LOG.info("Memory Used is: " + startingSize);
final String value = "value";
final String key = "key";
// Add the entry
jcs.put(key, value);
// Create 15 threads that read the keys;
final List <JCSTest.Executable> executables = new ArrayList <JCSTest.Executable> ();
for (int i = 0; i < 15; i++) {
final JCSTest.Executable executable = new JCSTest.Executable() {
public void execute() throws Exception {
for (int i = 0; i < 500; i++) {
final String key = "key" + i;
jcs.get(key);
}
jcs.get("key");
}
};
executables.add(executable);
}
//Create 15 threads that are insert 500 keys with large byte[] as values
for (int i = 0; i < 15; i++) {
final JCSTest.Executable executable = new JCSTest.Executable() {
public void execute() throws Exception {
// Add a bunch of entries
for (int i = 0; i < 500; i++) {
// Use a random length value
final String key = "key" + i;
byte[] value = new byte[10000];
jcs.put(key, value);
}
}
};
executables.add(executable);
}
runThreads(executables);
jcs.clear();
long finishingSize = measureMemoryUse();
LOG.info("Memory Used is: " + finishingSize);
return finishingSize - startingSize;
}
/**
* Runs a set of threads, for a fixed amount of time.
*/
protected void runThreads(final List <JCSTest.Executable> executables) throws Exception {
final long endTime = System.currentTimeMillis() + 10000;
final Throwable[] errors = new Throwable[1];
// Spin up the threads
final Thread[] threads = new Thread[executables.size()];
for (int i = 0; i < threads.length; i++) {
final JCSTest.Executable executable = executables.get(i);
threads[i] = new Thread() {
public void run() {
try {
// Run the thread until the given end time
while (System.currentTimeMillis() < endTime) {
executable.execute();
}
} catch (Throwable t) {
// Hang on to any errors
errors[0] = t;
}
}
};
threads[i].start();
}
// Wait for the threads to finish
for (int i = 0; i < threads.length; i++) {
threads[i].join();
}
// Throw any error that happened
if (errors[0] != null) {
throw new Exception("Test thread failed.", errors[0]);
}
}
/**
* Measure memory used by the VM.
*
* @return
* @throws InterruptedException
*/
protected long measureMemoryUse() throws InterruptedException {
System.gc();
Thread.sleep(3000);
System.gc();
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
}
/**
* A runnable, that can throw an exception.
*/
protected interface Executable {
/**
* Executes this object.
*
* @throws Exception
*/
void execute() throws Exception;
}
private int getListSize() {
final String listSize = "List Size";
final String lruMemoryCache = "LRU Memory Cache";
String result = "0";
IStats istats[] = jcs.getStatistics().getAuxiliaryCacheStats();
for (int i = 0; i < istats.length; i++) {
IStatElement statElements[] = istats[i].getStatElements();
if (lruMemoryCache.equals(istats[i].getTypeName())) {
for (int j = 0; j < statElements.length; j++) {
if (listSize.equals(statElements[j].getName())) {
result = statElements[j].getData();
}
}
}
}
return Integer.parseInt(result);
}
private int getMapSize() {
final String listSize = "Map Size";
String result = "0";
IStatElement statElements[] = jcs.getStatistics().getStatElements();
for (int i =0; i < statElements.length; i++) {
if (listSize.equals(statElements[i].getName())) {
result = statElements[i].getData();
}
}
return Integer.parseInt(result);
}
}
###################################################################################
# DEFAULT CACHE REGION
jcs.default=LJG
#jcs.default=
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=10000
jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.default.cacheattributes.UseMemoryShrinker=false
jcs.default.cacheattributes.MaxMemoryIdleTimeSeconds=3600
jcs.default.cacheattributes.ShrinkerIntervalSeconds=60
jcs.default.elementattributes=org.apache.jcs.engine.ElementAttributes
jcs.default.elementattributes.IsEternal=false
jcs.default.elementattributes.MaxLifeSeconds=3600
jcs.default.elementattributes.IdleTime=1800
jcs.default.elementattributes.IsSpool=true
jcs.default.elementattributes.IsRemote=true
jcs.default.elementattributes.IsLateral=true
jcs.auxiliary.LJG=org.apache.jcs.auxiliary.lateral.LateralCacheFactory
jcs.auxiliary.LJG.attributes=org.apache.jcs.auxiliary.lateral.LateralCacheAttributes
jcs.auxiliary.LJG.attributes.TransmissionTypeName=JAVAGROUPS
jcs.auxiliary.LJG.attributes.PutOnlyMode=true
jcs.auxiliary.LJG.attributes.TcpListenerPort=5000
jcs.auxiliary.LJG.attributes.JGChannelProperties=UDP(mcast_addr=224.10.10.10;mcast_port=5555;ip_ttl=32):PING(timeout=3000;num_initial_members=6):FD(timeout=3000):VERIFY_SUSPECT(timeout=1500):pbcast.NAKACK(gc_lag=10;retransmit_timeout=600,1200,2400,4800):UNICAST(timeout=600,1200,2400,4800):pbcast.STABLE(desired_avg_gossip=10000):FRAG:pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;shun=false;print_local_addr=true)
##############################################################
################## OPTIONAL THREAD POOL CONFIGURATION ###################
# Default thread pool config
thread_pool.default.boundarySize=2000
thread_pool.default.maximumPoolSize=150
thread_pool.default.minimumPoolSize=4
thread_pool.default.keepAliveTime=350000
#RUN ABORT WAIT BLOCK DISCARDOLDEST
thread_pool.default.whenBlockedPolicy=RUN
thread_pool.default.startUpSize=4
---------------------------------------------------------------------
To unsubscribe, e-mail: jcs-users-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jcs-users-help@jakarta.apache.org