`
jefferson
  • 浏览: 275562 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

关于OSCache的使用

阅读更多

听说OSCache的性能不行,我没测试过,但看到在应用过程中使用却非常广泛,因此对OSCache的使用看了一些资料,现对片断摘录如下:

OSCache.java

import java.util.Properties;

import com.opensymphony.oscache.base.EntryRefreshPolicy;
import com.opensymphony.oscache.base.NeedsRefreshException;
import com.opensymphony.oscache.base.persistence.CachePersistenceException;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;
import com.opensymphony.oscache.web.filter.ExpiresRefreshPolicy;
import com.util.*;

public class OSCache implements Cache {
 private GeneralCacheAdministrator cache;

 private static OSCache instance;

 public OSCache() {
  this.cache = new GeneralCacheAdministrator();
 }

 public OSCache(Properties prop) {
  this.cache = new GeneralCacheAdministrator(prop);
 }

 public synchronized static OSCache getInstance() {

  if (instance == null) {
   instance = new OSCache();
  }
  return instance;
 }

 public void setCacheCapacity(int cacheCapacity) {
  this.cache.setCacheCapacity(cacheCapacity);
 }

 public Object get(Object key) throws CachePersistenceException {
  try {
   return this.cache.getFromCache(String.valueOf(key));
  } catch (NeedsRefreshException e) {
   cache.cancelUpdate(String.valueOf(key));
   return null;
  }
 }

 public Object get(Object key, int time) throws CachePersistenceException {
  try {
   return this.cache.getFromCache(String.valueOf(key), time);
  } catch (NeedsRefreshException e) {
   cache.cancelUpdate(String.valueOf(key));
   return null;
  }
 }

 public Object getkey(int time) throws CachePersistenceException {

  String key = StrUtils.randomAlphanumeric(10);

  try {

   while (this.cache.getFromCache(key) != null) {
    key = StrUtils.randomAlphanumeric(10);
   }

   return key;

  } catch (NeedsRefreshException e) {
   return key;
  }
 }

 public void input(Object key, Object value)
   throws CachePersistenceException {
  this.cache.putInCache(String.valueOf(key), value);
 }

 public void input(Object key, Object value, int n)
   throws CachePersistenceException {

  EntryRefreshPolicy Policy = new ExpiresRefreshPolicy(n);

  this.cache.putInCache(String.valueOf(key), value, Policy);
 }

 public void remove(Object key) throws CachePersistenceException {
  this.cache.flushEntry(String.valueOf(key));
 }

 public void clear() throws CachePersistenceException {
  this.cache.flushAll();
 }

 public void destroy() throws CachePersistenceException {
  this.cache.destroy();
 }
}

//Cache.java接口

import com.opensymphony.oscache.base.persistence.CachePersistenceException;

public interface Cache {
 Object get(Object key) throws CachePersistenceException;

 Object get(Object key, int time) throws CachePersistenceException;

 void input(Object key, Object value) throws CachePersistenceException;

 void input(Object key, Object value, int i)
   throws CachePersistenceException;

 void remove(Object key) throws CachePersistenceException;

 void clear() throws CachePersistenceException;

 void destroy() throws CachePersistenceException;

 Object getkey(int time) throws CachePersistenceException;
}

 

//CacheManager .java

import java.util.*;

public class CacheManager {
 private static Map cacheMap = new HashMap();

 // private static Config config = ConfigManager.getConfig();
 private CacheManager() {
 }

 public static Cache getCache(Class clazz) {
  return getCache(clazz.getName());
 }

 public static Cache getCache() {
  return getCache();

 }

 public static Cache getCache(String cacheId) {
  Cache cache = null;
  cache = (Cache) cacheMap.get(cacheId);
  if (cache == null) {
   // cache = new OSCache(config.getProperties());
   cacheMap.put(cacheId, cache);
  }
  return cache;
 }

}

 


 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=778146

分享到:
评论
6 楼 jefferson 2009-05-03  
petehero 写道

Java开源文档(www.josdoc.com)希望转载您的文章,
如不同意请告知,谢谢!

可以
5 楼 luojiy 2009-02-16  
长见识了,
各位人兄的见解都很不错,小弟日前也是在学习OScache这个缓存框架。
4 楼 steve2010 2006-11-25  
好东西,
正在学习缓存!
3 楼 jefferson 2006-11-17  
与缓存相关的东西继续加。。。
看到一个缓存的例子, 控制类:UtilCache,里面有四个重要的属性,一是保存本身的hashMap,这是为了对把不同类型的缓存统一放到这个hashMap中,当然这个可以设置成控制类的静态属性。
二是保存数据的HashMap,还有一个LinkList类来控制data的生命周期,这个例子跟上述原理相似,不重述,不过保存data的类中用到了JAVA的软引用,这个概念平常接触比较少,因此在这里描述一下。
保存数据的类:
public static class CacheLine {
        public Object valueRef = null;

        public long loadTime = 0;

        public boolean useSoftReference = false;

        public CacheLine(Object value, boolean useSoftReference) {
            if (useSoftReference) {
                this.valueRef = new java.lang.ref.SoftReference(value);
            } else {
                this.valueRef = value;
            }
            this.useSoftReference = useSoftReference;
        }

        public CacheLine(Object value, boolean useSoftReference, long loadTime) {
            this(value, useSoftReference);
            this.loadTime = loadTime;
        }

        public Object getValue() {
            if (valueRef == null)
                return null;
            if (useSoftReference) {
                return ((java.lang.ref.SoftReference) valueRef).get();
            } else {
                return valueRef;
            }
        }

        public void setUseSoftReference(boolean useSoftReference) {
            if (this.useSoftReference != useSoftReference) {
                synchronized (this) {
                    this.useSoftReference = useSoftReference;
                    if (useSoftReference) {
                        this.valueRef = new java.lang.ref.SoftReference(this.valueRef);
                    } else {
                        this.valueRef = ((java.lang.ref.SoftReference) this.valueRef).get();
                    }
                }
            }
        }
    }

这里用到了java.lang.ref.SoftReference
不知道几类引用的区别,现在下面描述一下:
在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象。也就是说,只有对象处于可触及状态,程序才能使用它。这就像在日常生活中,从商店购买了某样物品后,如果有用,就一直保留它,否则就把它扔到垃圾箱,由清洁工人收走。一般说来,如果物品已经被扔到垃圾箱,想再把它捡回来使用就不可能了。

但有时候情况并不这么简单,你可能会遇到类似鸡肋一样的物品,食之无味,弃之可惜。这种物品现在已经无用了,保留它会占空间,但是立刻扔掉它也不划算,因为也许将来还会派上用场。对于这样的可有可无的物品,一种折衷的处理办法是:如果家里空间足够,就先把它保留在家里,如果家里空间不够,即使把家里所有的垃圾清除,也无法容纳那些必不可少的生活用品,那么再扔掉这些可有可无的物品。

从JDK 1.2版本开始,把对象的引用分为4种级别,从而使程序能更加灵活地控制对象的生命周期。这4种级别由高到低依次为:强引用、软引用、弱引用和虚引用。

1.强引用(StrongReference)
本章前文介绍的引用实际上都是强引用,这是使用最普遍的引用。如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

2.软引用(SoftReference)
如果一个对象只具有软引用,那就类似于可有可无的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

3.弱引用(WeakReference)
如果一个对象只具有弱引用,那就类似于可有可无的生活用品。弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

4.虚引用(PhantomReference)
“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

2 楼 jefferson 2006-11-17  
Cache 的代码片断:
public class Cache implements Cacheable {

    /**

     * 因为System.currentTimeMillis()执行非常耗费性能,因此如果get操作都执行

* 这条语句将会形成性能瓶颈, 通过一个全局时间戳来实现每秒更新

* 当然,这意味着在缓存过期时间计算上有一到几秒的误差

     */

    protected static long currentTime = CacheTimer.currentTime;

    //CacheObject对象

    protected HashMap cachedObjectsHash;

    //accessed LinkedList 最经常访问的排列在最前面

    protected LinkedList lastAccessedList;

    //以缓存加入顺序排列,最后加入排在最前面;越早加入的排在最后面

    protected LinkedList ageList;

    //缓存最大限制 默认是128k 可根据内存设定,越大性能越高

    protected int maxSize =  128 * 1024;

    //当前缓存的大小

    protected int size = 0;

    //最大生命周期时间,默认是没有

    protected long maxLifetime = -1;

    //缓存的击中率,用于评测缓存效率

    protected long cacheHits, cacheMisses = 0L;



    public Cache() {

        // 构造HashMap. 默认capacity 是11

        // 如果实际大小超过11,HashMap将自动扩充,但是每次扩充都

// 是性能开销,因此期初要设置大一点

        cachedObjectsHash = new HashMap(103);

        lastAccessedList = new LinkedList();

        ageList = new LinkedList();

    }

    public Cache(int maxSize) {

        this();

        this.maxSize = maxSize;

    }

    public Cache(long maxLifetime) {

        this();

        this.maxLifetime = maxLifetime;

    }

    public Cache(int maxSize, long maxLifetime) {

        this();

        this.maxSize = maxSize;

        this.maxLifetime = maxLifetime;

    }

    public int getSize() {        return size;    }

    public int getMaxSize() {        return maxSize;    }



    public void setMaxSize(int maxSize) {

        this.maxSize = maxSize;

        // 有可能缓存大小超过最大值,需要激活删除清理动作

        cullCache();

    }

    public synchronized int getNumElements() {

        return cachedObjectsHash.size();

    }



    /**

     * 增加一个Cacheable对象

* 因为HashMap不是线程安全的,所以操作方法要使用同步

* 如果使用Hashtable就不必同步

     */

    public synchronized void add(Object key, Cacheable object) {

        // 删除已经存在的key

        remove(key);

        int objectSize = object.getSize();

        // 如果被缓存对象的大小超过最大值,就放弃

        if (objectSize > maxSize * .90) {            return;        }

        size += objectSize;

        //创建一个CacheObject对象

        CacheObject cacheObject = new CacheObject(object, objectSize);

        cachedObjectsHash.put(key, cacheObject);  //保存这个CacheObject

        // 加入accessed LinkedList,Jive自己的LinkedList在加入时可以返回值

        LinkedListNode lastAccessedNode = lastAccessedList.addFirst(key);

        // 保存引用

        cacheObject.lastAccessedListNode = lastAccessedNode;

        // 加入到age LinkedList

        LinkedListNode ageNode = ageList.addFirst(key);

        // 这里直接调用System.currentTimeMillis();用法值得讨论

        ageNode.timestamp = System.currentTimeMillis();

        // 保存引用

        cacheObject.ageListNode = ageNode;

        // 做一些清理工作

        cullCache();

    }

    /**

     * 从缓存中获得一个被缓存的对象,这个方法在下面两种情况返回空

     *    <li>该对象引用从来没有被加入缓存中

     *    <li>对象引用因为过期被清除</ul>

     */

    public synchronized Cacheable get(Object key) {

        // 清除过期缓存

        deleteExpiredEntries();

        //以Key从缓存中获取一个对象引用

        CacheObject cacheObject = (CacheObject)cachedObjectsHash.get(key);

        if (cacheObject == null) {

            // 不存在,增加未命中率

            cacheMisses++;

            return null;

        }

        // 存在,增加命中率

        cacheHits++;

        // 从accessed LinkedList中将对象从当前位置删除

        // 重新插入在第一个

        cacheObject.lastAccessedListNode.remove();

        lastAccessedList.addFirst(cacheObject.lastAccessedListNode);

        return cacheObject.object;

    }

    …

}

1 楼 jefferson 2006-11-17  
以下是jive的缓存实现的原理的介绍,对缓存原理的实现一些参考:

Jive的Cache总体来说实现得不是非常精简和有效。它是针对每个具体数据对象逐个实现缓冲,这种“穷尽”的办法不是实践所推荐的用法。通过使用动态代理模式,可以根据具体方法的不同来实现缓存是值得推荐的做法。Jive的缓存实现得比较简单,可以用来学习和研究缓存机制。

Jive中的Cache实现了缓存机制的大部分行为,它是将对象用惟一的关键字Key作标识保存在HashMap或Hashtable中。当然,必须知道这些对象的大小,这个前提条件的设定可以保证缓存增长时不会超过规定的最大值。

如果缓存增长得太大,一些不经常被访问的对象将首先从缓存中删除。如果设置了对象的最大生命周期时间,即使这个对象被反复频繁访问,也将从缓存中删除。这个特性可以适用于一些周期性需要刷新的数据,如来自数据库的数据。

在Cach中除了getObject()方法的性能依据缓存大小,其他方法的性能都是比较快的。一个HashMap用来实现快速寻找,两个LinkedList中一个以一定的访问顺序来保存对象,叫accessed LinkedList;另外一个以它们加入缓存的顺序保存这些对象,这种保存对象只是保存对象的引用,叫 age LinkedList。注意,这里的LinkedList不是JDK中的LinkedList,而是Jive自己定义的LinkedList。

当对象被加入缓存时,首先被CacheObject封装。封装有以下信息:对象大小(以字节计算),一个指向accessed LinkedList的引用,一个指向age LinkedList的引用。

当从缓存中获取一个对象如ObjectA时,首先,HashMap寻找到指向封装ObjectA等信息的CacheObject对象。然后,这个对象将被移动到accessed LinkedList的前面,还有其他一些动作如缓存清理、删除、过期失效等都是在这个动作中一起触发实现的。

缓存中对象是原对象的映射,如何确保缓存中对象和原对象的一致性?即当原对象发生变化时,缓存中的对象也必须立即更新。这是缓存机制需要解决的另外一个基本技术问题。

Jive中是在原对象发生变化时,立即进行清除缓存中对象,如ForumMessage对象的创建。在DbForumThread的AddMessage方法中有下列语句:

factory.cacheManager.threadCache.remove(this.id);

factory.cacheManager.forumCache.remove(this.forumID);

即当有新的帖子加入时,将ForumThreadCache和ForumCache相关缓冲全部清除。这样,当有相关对象读取时,将直接从数据库中读取,这是一种非常简单的缓存更新方式。

在复杂的系统,例如有一台以上的服务器运行着Jive系统。如果一个用户登陆一台服务器后,通过这台服务器增加新帖。那么按照上述原理,只能更新本服务器JVM中的缓存数据,而其他服务器则无从得知这种改变,这就需要一种分布式的缓存机制。

相关推荐

    Oscache使用教程

    Oscache使用教程,基础教程。详细介绍几本原理以及几本配置。

    oscache的使用

    oscache的使用

    oscache 使用介紹

    OSCache是OpenSymphony这个开源项目众多Projects中的一个。他是一个高效的J2EE缓存框架,能够很好的解决动态网站速度的问题。

    OSCache使用文档

    OSCache使用文档OSCache使用文档OSCache使用文档OSCache使用文档OSCache使用文档OSCache使用文档OSCache使用文档OSCache使用文档OSCache使用文档

    Oscache使用手册

    Cache是一种用于提高系统响应速度、改善系统运行性能的技术。尤其是在Web应用中,通过缓存页面的...OSCache是个一个被广泛采用的高性能的J2EE缓存框架,OSCache还能应用于任何Java应用程序的普通的缓存解决方案。。。。

    oscache的使用实例和详解

    缓存框架oscache 的使用实例和详细解释,

    OSCache配置说明文档

    OSCache由OpenSymphony设计,它是一种开创性的JSP定制标记应用,提供了在现有JSP页面之内实现快速内存缓冲的功能。OSCache是一个广泛采用的高性能的J2EE缓存框架,OSCache能用于任何Java应用程序的普通的缓存解决...

    OsCache缓存框架使用示例

    这里结合 天气预报的webservice 展示了OsCache框架的具体使用方法 项目可直接运行 ,代码简洁清晰

    oscache-2.1.jar

    oscache-2.1.jar oscache-2.1.jar

    oscache,缓存机制的使用

    oscache,java,缓存机制的使用

    oscache缓存使用总结.doc

    oscache缓存使用总结

    oscache(JSP定制标记应用)

    javaweb做页面缓存常用,OSCache是一个工业级的J2EE缓存实现。OSCache不但能缓存java对象,还可以缓存页面,http请求和二进制内容,例如pdf文件等。通过应用OSCache,我们不但可以实现通常的Cache功能,还能够改善...

    Oscache框架的搭建步骤

    使用oscache进行缓存,大大提高web系统运行效率

    用OSCache进行缓存对象

    1、OSCache是什么? 2、OSCache的特点 3、有关“用OSCache进行缓存对象”的研究

    oscache-java缓存框架

    oscache-java缓存框架插件和安装教程,使用教程一步到位

    oscache缓存技术入门实例

    oscache缓存技术入门实例

    OSCache学习例子 实例

    OSCache学习例子 实例 很好的与j2ee结合

    oscache文档

    OSCache标记库由OpenSymphony设计,它是一种开创性的JSP定制标记应用,提供了在现有JSP页面之内实现快速内存缓冲的功能。OSCache是个一个广泛采用的高性能的J2EE缓存框架,OSCache能用于任何Java应用程序的普通的...

    oscache的例子

    OSCache标记库由OpenSymphony设计,它是一种开创性的缓存方案,它提供了在现有JSP页面之内实现内存缓存的功能。OSCache是个一个被广泛采用的高性能的J2EE缓存框架,OSCache还能应用于任何Java应用程序的普通的缓存...

    教你如何用好oscache的详细文档

    oscache的详细文档,很easy,好好用。

Global site tag (gtag.js) - Google Analytics