Jive与Ofbiz的Cache机制比较 请大家讨论

Jive与Ofbiz都用实现了Cache机制,两者的原理都很类似,就是把所要缓存的对象加到HashMap哈希映射表中,用两个链表分别维持着缓存对象

和每个缓存对象的生命周期。如果一个缓存对象被访问到,那么就把它放到链表的最前面,然后不定时地把要缓存的对象加入链表中,把过期

对象删除,如此反复。

在Jive(Jive2.6.0)中用到了Cache\Cacheable\CacheObject\CacheSizes\DefaultCache\LinkdList\LinkdListNode等类;
而在Ofbiz中,只用了一个类:UtilCache!!

在此比较一下他们的实现差异:

1、在Jive中有一个Cacheable接口,只有一个方法getCachedSize()


public interface Cacheable extends Serializable {
public int getCachedSize();
}

所有需要Cache的对象都必须implements该接口并实现getCachedSize(),其目的是为了在缓存的时候得到对象的大小。
当调用DefaultCache中的put方法的时候,会得到该对象的大小:

public synchronized Object put(Object key, Object value)
{
remove(key);
int objectSize = calculateSize(value);
if(maxCacheSize > 0 && (double)objectSize > (double)maxCacheSize * 0.9)
{
Log.warn("Cache: " + name + " -- object with key " + key + " is too large to fit in cache. Size is " +

objectSize);
return value;
} else
{
cacheSize += objectSize;
CacheObject cacheObject = new CacheObject(value, objectSize);
map.put(key, cacheObject);
LinkedListNode lastAccessedNode = lastAccessedList.addFirst(key);
cacheObject.lastAccessedListNode = lastAccessedNode;
LinkedListNode ageNode = ageList.addFirst(key);
ageNode.timestamp = System.currentTimeMillis();
cacheObject.ageListNode = ageNode;
cullCache();
return value;
}
}

protected int calculateSize(Object object)
{
if(object instanceof Cacheable)
return ((Cacheable)object).getCachedSize();
......
}

而在Ofbiz中根本都不关心每个对象的Size,只关心总体的HashMap的Size,他的代码如下:

public synchronized void put(Object key, Object value) {
if (key == null)
return;

if (maxSize > 0) {
// when maxSize is changed, the setter will take care of filling the LRU list
if (cacheLineTable.containsKey(key)) {
keyLRUList.remove(key);
keyLRUList.addFirst(key);
} else {
keyLRUList.addFirst(key);
}
}

if (expireTime > 0) {
cacheLineTable.put(key, new UtilCache.CacheLine(value, useSoftReference, System.currentTimeMillis()));
} else {
cacheLineTable.put(key, new UtilCache.CacheLine(value, useSoftReference));
}
if (maxSize > 0 && cacheLineTable.size() > maxSize) {
Object lastKey = keyLRUList.getLast();
remove(lastKey);
}
}

个人觉得,Ofbiz中处理得更简洁,其实不就是判断缓存是否> maxSize吗!用HashMap.Size()我觉得足以了,而且对于Jive的方式,每个需要

Cache的对象必须implements Cache接口,较麻烦。
当然是否有其他妙处就不得而知了,还请各位高人指点。

2、链表的问题也挺有意思,Jive为了实现双向联表用了两个类:LinkdList\LinkdListNode,记录最近访问的对象列表和按时间顺序排列的对象列表。
而在Ofbiz中用的是java.util.LinkedList:
public LinkedList keyLRUList = new LinkedList();
功能上好像也没有什么两样,不知道Jive问什么还要如此破费周折?还请各位高人指点。

3、Ofbiz中对象过时清除功能写得很一般,他是在get方法中实现的:


public Object get(Object key) {

UtilCache.CacheLine line = (UtilCache.CacheLine) cacheLineTable.get(key);

if (hasExpired(line)) {//如果过期
remove(key);
line = null;
}

if (line == null) {
// remove掉后还要告诉我过期!!
missCount++;
return null;
}
}

Jive中实现的就巧妙多了,而且在这上面写得较精彩.

个人认为两者实现的功能相当,Ofbiz代码更简单,就是不知道两者的性能究竟怎样,请各位高人多多指教,请讨论。

sailingyangjian@hoatmail.com

没有人研究过吗?
自己顶一下!

对于第二个问题,我的感觉是,那个程序员是学C++出身的,对JAVA的包还不是很了解

Jive的缓存因为知道数据大小,因此可以让管理者调节缓存大小,根据访问量大小调节,比较方便。缺点是重用性差,移植麻烦。

Ofbiz的缓存重用性很好,可以作为自己的系统缓存用,当然在缓存的精确控制上不及Jive。

使用哪一种缓存取决于自己的选择,关键是,这两种缓存不支持分布式,要实现分布式缓存就相当复杂,Jive 3.0以后就使用了一个非开源的分布式缓存产品。TTS也是。

PinkFloyd,老大能否上传一份ofbiz源码?

最近在我自己的网站上运用了类似于JIVE的CACHE实现,但感觉和直接操作数据库的速度差不多!
好象JIVE当中CACHE的移植并不难啊,UTIL包都可以直接拿到自己的系统中使用啊。

现在用nio包实现的mmf我觉得会更好

有人有ofbiz的源码吗?大家一起研究一下

to banq

请问你知道jive3.0用的那个缓存包叫什么名字吗?那里有下载的。谢谢了。