I want to use JCS as a cache for a large number of objects, where I'll have all 
of the objects in the indexed disk cache, and about 10% in memory.

What I've found is that JCS is using about 300 bytes of memory for each item in 
the disk cache.  This is contrary to my expectation based on 
http://jakarta.apache.org/jcs/IndexedDiskAuxCache.html "Depending on the key 
size, 500,000 disk entries will probably only require about 3 MB of memory." 
which implies about 6 bytes per item of overhead.

Here is my test program.  Note that it waits until after the purgatory objects 
have been written to disk before doing the GC and heap calc.

/* $Header$ */

import org.apache.jcs.JCS;

import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class JcsTest {
    JcsTest() {
    }

    public static class TestData implements Serializable {
        int n;
        String key;
        String v1;
        String v2;
        String v3;
        String v4;
        String v5;
        String v6;
        public TestData(int n) {
            this.n = n;
            this.key = Integer.toString(n);
            v1 = this.key;
            v2 = this.key + this.key;
            v3 = this.key + this.key + this.key;
            v4 = this.key + this.key + this.key + this.key;
            v5 = this.key + this.key + this.key + this.key + this.key;
            v6 = this.key + this.key + this.key + this.key + this.key
              + this.key;
        }
        public String getKey() {
            return this.key;
        }
    }

    void lookupTest(JCS cache, int numObjs,
      int nTrials, int nOps) throws Exception {
        Random rand = new Random();
        int max = numObjs - 1;
        for (int trial = 0; trial < nTrials; trial++) {
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < nOps; i++) {
                int x = rand.nextInt(max);
                Object item = cache.get(Integer.toString(x));
                if (item == null)
                    throw new Exception("PANIC: can't find item: " + x);
            }
            long elapsed = System.currentTimeMillis() - startTime;
            System.out.printf("TEST rand access trial %d: %d in %d ms, %d / 
sec\n",
              trial, nOps, elapsed,
              (int)(((double)nOps / (double)elapsed) * 1000.0));
        }

        for (int trial = 0; trial < nTrials; trial++) {
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < nOps; i++) {
                Object item = cache.get(Integer.toString(i % max));
                if (item == null)
                    throw new Exception("PANIC: can't find item: " + i);
            }
            long elapsed = System.currentTimeMillis() - startTime;
            System.out.printf("TEST repeat access trial %d: %d in %d ms, %d / 
sec\n",
              trial, nOps, elapsed,
              (int)(((double)nOps / (double)elapsed) * 1000.0));
        }
    }

    long memCheck(String msg, long baseline) {
        System.gc();
        long currentMem = (Runtime.getRuntime().totalMemory()
          - Runtime.getRuntime().freeMemory()) / 1000;
        if (baseline != -1) {
            System.out.printf("TEST %s: %d KB, delta %d KB\n",
              msg, currentMem, currentMem - baseline);
        } else {
            System.out.printf("TEST %s: %d KB\n",
              msg, currentMem);
        }
        return currentMem;
    }

    void doit(String configFilePath, int numObjs, int numTrials, int numOps)
      throws Exception {
        long startMem = memCheck("STARTING heap size", -1);

        long startTime = System.currentTimeMillis();
        JCS cache = JCS.getInstance("testCache1");
        for (int i = 0; i < numObjs; i++) {
            cache.put(Integer.toString(i), new TestData(i));
        }
        long elapsed = System.currentTimeMillis() - startTime;

        System.out.println("TEST: CACHE STATS: " + cache.getStats());
        System.out.println("TEST: Sleeping 15 sec to let objs roll to disk");
        Thread.sleep(15000);
        System.out.println("TEST: CACHE STATS: " + cache.getStats());

        long afterCacheLoadMem = memCheck("after cache load", startMem);

        lookupTest(cache, numObjs, numTrials, numOps);

        cache.clear();
        cache.dispose();
    }

    public static void main(String[] args) {
        try {
            if (args.length != 4) {
                System.err.println(
                  "usage: JcsTest configFile numObjs numTrials numOps");
                System.exit(0);
            }
            JcsTest tester = new JcsTest();
            tester.doit(args[0],
              Integer.valueOf(args[1]),
              Integer.valueOf(args[2]),
              Integer.valueOf(args[3]));
        } catch (Exception e) {
            System.out.println("JcsTest failed: " + e);
            e.printStackTrace();
        }
    }
}

Cache config file:

##############################################################
##### Default Region Configuration
jcs.default=DC
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=10000
jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
# The JSC docs incorrectly name this property DiskUsagePattern.
jcs.default.cacheattributes.DiskUsagePatternName=UPDATE

##############################################################
##### AUXILIARY CACHES
# Indexed Disk Cache
jcs.auxiliary.DC=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory
jcs.auxiliary.DC.attributes=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
jcs.auxiliary.DC.attributes.DiskPath=jcs_swap
jcs.auxiliary.DC.attributes.MaxPurgatorySize=1000000
# MaxKeySize=0 means no limit on number of objects cached on disk
jcs.auxiliary.DC.attributes.MaxKeySize=-1
jcs.auxiliary.DC.attributes.OptimizeAtRemoveCount=300000
jcs.auxiliary.DC.attributes.OptimizeOnShutdown=true
jcs.auxiliary.DC.attributes.MaxRecycleBinSize=7500

heap size output for loading 10k objects into the cache:

out-mem10k-objs10k:TEST STARTING heap size: 2787 KB
out-mem10k-objs10k:TEST after cache load: 11023 KB, delta 8236 KB

heap size output for loading 100k objects into the cache:

out-mem10k-objs100k:TEST STARTING heap size: 2787 KB
out-mem10k-objs100k:TEST after cache load: 47087 KB, delta 44300 KB

heap size output for loading 200k objects into the cache:

out-mem10k-objs200k:TEST STARTING heap size: 2787 KB
out-mem10k-objs200k:TEST after cache load: 66597 KB, delta 63810 KB

So using the 11023 KB as our baseline, adding 190K more objects resulted in an 
increase in heap of 55574 KB, or 292.5 bytes per object.

This is using the latest JCS software, using Java 6 update 3, on RedHat Linux.  
On and I rm the jcs-swap files before each run.

Am I missing something?  Is there some magic knob I forgot to twist that would 
get this overhead way down?

Thanks,

Nick

PS: for absolute completeness, here is the full output from the 200k object run:

=========================================================================


TEST STARTING heap size: 2787 KB
Sep 3, 2008 3:45:51 PM org.apache.jcs.engine.control.CompositeCacheManager 
configure
INFO: Creating cache manager from config file: /cache.ccf
Sep 3, 2008 3:45:51 PM org.apache.jcs.utils.threadpool.ThreadPoolManager 
loadConfig
INFO: thread_pool.default PoolConfiguration = useBoundary = [true] boundarySize 
= [2000] maximumPoolSize = [150] minimumPoolSize = [4] keepAliveTime = [300000] 
whenBlockedPolicy = [RUN] startUpSize = [4]
Sep 3, 2008 3:45:51 PM org.apache.jcs.engine.control.CompositeCacheConfigurator 
setDefaultAuxValues
INFO: Setting default auxiliaries to DC
Sep 3, 2008 3:45:51 PM org.apache.jcs.engine.control.CompositeCacheConfigurator 
setDefaultCompositeCacheAttributes
INFO: setting defaultCompositeCacheAttributes to [ useLateral = true, useRemote 
= true, useDisk = true, maxObjs = 10000, maxSpoolPerRun = -1, diskUsagePattern 
= 1 ]
Sep 3, 2008 3:45:51 PM org.apache.jcs.engine.control.CompositeCacheConfigurator 
parseElementAttributes
INFO: No special ElementAttribute class defined for key 
[jcs.default.elementattributes], using default class.
Sep 3, 2008 3:45:51 PM org.apache.jcs.engine.control.CompositeCacheConfigurator 
setDefaultElementAttributes
INFO: setting defaultElementAttributes to [ IS_LATERAL = true, IS_SPOOL = true, 
IS_REMOTE = true, IS_ETERNAL = true, MaxLifeSeconds = -1, IdleTime = -1, 
CreateTime = 1220471151384, LastAccessTime = 1220471151384, 
getTimeToLiveSeconds() = -1, createTime = 1220471151384 ]
Sep 3, 2008 3:45:51 PM org.apache.jcs.engine.control.CompositeCacheConfigurator 
parseRegions
INFO: Parsed regions []
Sep 3, 2008 3:45:51 PM org.apache.jcs.engine.control.CompositeCacheConfigurator 
doConfigure
INFO: Finished configuration in 17 ms.
Sep 3, 2008 3:45:51 PM org.apache.jcs.engine.control.CompositeCacheConfigurator 
parseElementAttributes
INFO: No special ElementAttribute class defined for key 
[jcs.region.testCache1.elementattributes], using default class.
Sep 3, 2008 3:45:51 PM org.apache.jcs.engine.memory.lru.LRUMemoryCache 
initialize
INFO: initialized LRUMemoryCache for testCache1
Sep 3, 2008 3:45:51 PM org.apache.jcs.engine.control.CompositeCache <init>
INFO: Constructed cache with name [testCache1] and cache attributes [ 
useLateral = true, useRemote = true, useDisk = true, maxObjs = 10000, 
maxSpoolPerRun = -1, diskUsagePattern = 1 ]
Sep 3, 2008 3:45:51 PM org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCache 
<init>
INFO: Region [testCache1] Cache file root directory: jcs_swap
Sep 3, 2008 3:45:51 PM org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCache 
initKeyMap
INFO: Region [testCache1] Set maxKeySize to unlimited'
Sep 3, 2008 3:45:51 PM org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCache 
<init>
INFO: Region [testCache1] Indexed Disk Cache is alive.
Sep 3, 2008 3:45:51 PM org.apache.jcs.engine.CacheEventQueue put
INFO: Cache event queue created: CacheEventQueue [listenerId=700406631, 
cacheName=testCache1]
TEST: CACHE STATS: Region Name = testCache1
HitCountRam = 0
HitCountAux = 0
---------------------------LRU Memory Cache
List Size = 9998
Map Size = 9998
Put Count = 200000
Hit Count = 0
Miss Count = 0
---------------------------Indexed Disk Cache
Is Alive = true
Key Map Size = 33404
Data File Length = 22937956
Hit Count = 0
Bytes Free = 0
Optimize Operation Count = 0
Times Optimized = 0
Recycle Count = 0
Recycle Bin Size = 0
Startup Size = 0
Purgatory Hits = 0
Purgatory Size = 166594
Working = true
Alive = true
Empty = false
Size = 166593
TEST: Sleeping 15 sec to let objs roll to disk
TEST: CACHE STATS: Region Name = testCache1
HitCountRam = 0
HitCountAux = 0
---------------------------LRU Memory Cache
List Size = 9998
Map Size = 9998
Put Count = 200000
Hit Count = 0
Miss Count = 0
---------------------------Indexed Disk Cache
Is Alive = true
Key Map Size = 200000
Data File Length = 140755580
Hit Count = 0
Bytes Free = 0
Optimize Operation Count = 0
Times Optimized = 0
Recycle Count = 0
Recycle Bin Size = 0
Startup Size = 0
Purgatory Hits = 0
Purgatory Size = 0
Working = true
Alive = true
Empty = true
Size = 0
TEST after cache load: 66597 KB, delta 63810 KB
TEST rand access trial 0: 5000 in 1068 ms, 4681 / sec
TEST rand access trial 1: 5000 in 667 ms, 7496 / sec
TEST rand access trial 2: 5000 in 545 ms, 9174 / sec
TEST rand access trial 3: 5000 in 442 ms, 11312 / sec
TEST rand access trial 4: 5000 in 406 ms, 12315 / sec
TEST rand access trial 5: 5000 in 379 ms, 13192 / sec
TEST rand access trial 6: 5000 in 403 ms, 12406 / sec
TEST rand access trial 7: 5000 in 405 ms, 12345 / sec
TEST rand access trial 8: 5000 in 407 ms, 12285 / sec
TEST rand access trial 9: 5000 in 406 ms, 12315 / sec
TEST repeat access trial 0: 5000 in 367 ms, 13623 / sec
TEST repeat access trial 1: 5000 in 11 ms, 454545 / sec
TEST repeat access trial 2: 5000 in 11 ms, 454545 / sec
TEST repeat access trial 3: 5000 in 11 ms, 454545 / sec
TEST repeat access trial 4: 5000 in 11 ms, 454545 / sec
TEST repeat access trial 5: 5000 in 11 ms, 454545 / sec
TEST repeat access trial 6: 5000 in 11 ms, 454545 / sec
TEST repeat access trial 7: 5000 in 11 ms, 454545 / sec
TEST repeat access trial 8: 5000 in 11 ms, 454545 / sec
TEST repeat access trial 9: 5000 in 11 ms, 454545 / sec
Sep 3, 2008 3:46:15 PM org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCache 
reset
WARNING: Region [testCache1] Reseting cache
Sep 3, 2008 3:46:15 PM org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCache 
initKeyMap
INFO: Region [testCache1] Set maxKeySize to unlimited'
Sep 3, 2008 3:46:15 PM org.apache.jcs.engine.control.CompositeCache dispose
INFO: In DISPOSE, [testCache1] fromRemote [false] 
Region Name = testCache1
HitCountRam = 47707
HitCountAux = 52293
---------------------------LRU Memory Cache
List Size = 0
Map Size = 0
Put Count = 252293
Hit Count = 47707
Miss Count = 52293
---------------------------Indexed Disk Cache
Is Alive = true
Key Map Size = 0
Data File Length = 0
Hit Count = 52293
Bytes Free = 0
Optimize Operation Count = 0
Times Optimized = 0
Recycle Count = 0
Recycle Bin Size = 0
Startup Size = 0
Purgatory Hits = 0
Purgatory Size = 0
Working = true
Alive = false
Empty = true
Size = 0
Sep 3, 2008 3:46:15 PM org.apache.jcs.engine.control.CompositeCache dispose
INFO: In DISPOSE, [testCache1] auxiliary [EMAIL PROTECTED]
Sep 3, 2008 3:46:15 PM org.apache.jcs.engine.control.CompositeCache dispose
INFO: In DISPOSE, [testCache1] put 0 into auxiliary [EMAIL PROTECTED]
Sep 3, 2008 3:46:15 PM org.apache.jcs.auxiliary.disk.AbstractDiskCache$1 run
INFO: No longer waiting for event queue to finish: Cache Event Queue
Working = true
Alive = false
Empty = true
Size = 0
Sep 3, 2008 3:46:15 PM org.apache.jcs.auxiliary.disk.AbstractDiskCache dispose
INFO: In dispose, destroying event queue.
Sep 3, 2008 3:46:15 PM org.apache.jcs.engine.CacheEventQueue destroy
INFO: Destroy was called after queue was destroyed.  Doing nothing.  Stats =  
Cache Event Queue
Working = true
Alive = false
Empty = true
Size = 0
Sep 3, 2008 3:46:15 PM org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCache 
disposeInternal
INFO: Region [testCache1] Shutdown complete.
Sep 3, 2008 3:46:15 PM org.apache.jcs.engine.control.CompositeCache dispose
INFO: In DISPOSE, [testCache1] disposing of memory cache.
Sep 3, 2008 3:46:15 PM org.apache.jcs.engine.memory.AbstractMemoryCache dispose
INFO: Memory Cache dispose called.  Shutting down shrinker thread if it is 
running.


      

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to