转自:https://www.cnblogs.com/crazylqy/p/4238148.html

目录

1     堆内存(MemoryStore)

1.1     指定可用内存

1.2     驱除策略

1.3     元素过期

2     非堆内存(BigMemory)

3     磁盘(DiskStore)

3.1     指定可用容量

3.2     元素过期

在Ehcache中对于缓存的存储主要有三种方式:分别是堆内存、非堆内存和磁盘。其中非堆内存是针对于企业版Ehcache才有的功能,它可以不受Java GC的影响,能够创建很大的缓存。

1       堆内存(MemoryStore)

我们通常所有的MemoryStore实际上就是堆内存存储。MemoryStore总是可用的,所有的元素都可以储存在MemoryStore中。MemoryStore是线程安全的,相比另外两种储存方式而言其访问速度也是最快的。通常我们在往缓存里面添加元素的时候,其首先就是存放在MemoryStore里面的,但是我们又不能说连续不断的往MemoryStore里面存放元素,这就涉及到到底能放多少元素的问题。

1.1         指定可用内存

Ehcache规定我们在使用一个Cache时必须在CacheManager级别指定可用的内存大小或者是在Cache级别指定可用的内存大小或所允许存放的元素的最大数量。在CacheManager级别指定的内存大小是其内部所有Cache一起所能使用的内存的最大量。CacheManager级别指定内存大小是通过maxBytesLocalHeap来指定的,如:

 <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
maxBytesLocalHeap="500M"> </ehcache>

上面指定了我们的CacheManager所能使用的最大内存是500M。CacheManager级别指定了内存大小后我们在Cache上也可以指定其能使用的最大内存,但不能指定其所能存储元素的最大数量。另外,如果我们的CacheManager没有指定可用的内存大小,我们可以通过maxBytesLocalHeap在Cache级别指定可用的内存大小,或者通过maxEntriesLocalHeap在Cache级别指定允许储存元素的最大数量,但是maxEntriesLocalHeap和maxBytesLocalHeap不能同时使用。如下在CacheManager级别使用maxBytesLocalHeap,然而在Cache级别使用maxEntriesLocalHeap是不行的。

 <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
maxBytesLocalHeap="500M"> <cache name="ttt" maxEntriesLocalHeap="10000"/> </ehcache>

如下在Cache级别同时使用maxBytesLocalHeap和maxEntriesLocalHeap也是不行的。

 <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"> <cache name="ttt" maxBytesLocalHeap="50M" maxEntriesLocalHeap="10000"/> </ehcache>

1.2     驱除策略

那么当我们内存中的元素大小或者数量超过了预设的大小之后怎么办呢?这个时候如果我们设置了允许溢出,如overflowToDisk或overflowToOffHeap,则会把某些元素溢出到对应的储存器中。如果不允许溢出,则会先删除原有的某些元素。至于是哪个元素溢出、哪个元素删除则在不存在超时的情况下与我们的内存驱除策略有关,这是通过Cache的memoryStoreEvictionPolicy属性来指定的。其可选值有LRU、LFU和FIFO,默认是LRU。但是如果有过期元素存在的话则会优先驱除已经过期的元素,然后再考虑驱除策略memoryStoreEvictionPolicy。

LRU(Least Recently Used:最近最少使用。当我们把一个元素储存到Cache中或者从Cache中取出时都会更新该元素的最后使用时间。当采用最近最少使用原则进行驱除时会优先把最后使用时间最早的元素进行驱除。

LFU(Least Frequently Used:最不常使用的。每次我们从Cache中获取一个元素时都会更新该元素的hitCount属性值加1。当采用最不常使用原则进行驱除时hitCount属性值最小的元素将优先驱除。

FIFO(First In First Out:先进先出。当采用这种驱除原则时将优先驱除最先储存的元素。

1.3     元素过期

在上文中我们已经知道在不存在元素过期的情况下,驱除哪个元素是与我们的内存驱除策略有关的。但如果存在过期元素的话则会优先驱除已经过期的元素。关于控制元素是否过期我们可以通过cache的几个属性来定义。

timeToIdleSeconds:单位是秒,表示一个元素在不被请求的情况下允许在缓存中存在的最长时间。默认值是0,表示不限制。

timeToLiveSeconds:单位是秒,表示一个元素不管有没有被使用,其在缓存中允许存在的最长时间。默认是0,表示不限制。一般timeToLiveSeconds要比timeToIdleSeconds长,否则就timeToIdleSeconds就失去意义了。

eternal:boolean类型,表示是否永恒,默认为false。当设为true时,表示缓存中的元素永远不会过期,timeToIdleSeconds和timeToLiveSeconds就失去作用了。这个时候元素就只能由驱除策略来进行驱除了。

当我们的元素过期以后,为了保持Cache的性能,Ehcache不一定马上就会将过期的元素删除或者驱除到其它存储容器中,它可能还在原来的位置。之所以说不一定是因为有可能当一个元素过期时恰好Cache需要删除元素或者驱除元素到其它存储容器中,这个时候我们的过期元素将优先被删除或者驱除。另外,当我们在请求一个元素的时候,如果Ehcache发现该元素已经过期的话也会立刻将该元素删除。

 <cache name="ttt" maxBytesLocalHeap="50M" timeToIdleSeconds="600"
timeToLiveSeconds="3600" memoryStoreEvictionPolicy="LFU" />

在上面的配置中,我们指定了该Cache允许元素不被请求的时间是10分钟,最大存活时间是1小时,使用的驱除策略是LFU(最不常使用)。

2       非堆内存(BigMemory)

非堆内存存储是针对于企业版才有的功能,它可以不受Java GC的影响,能够创建很大的缓存。BigMemory保存的都是一个个的字节,在保存元素的时候Ehcache会对元素进行序列化再保存到BigMemory中,然后在读取的时候又会把读取到的字节进行反序列化。所以存放在其中的元素的key和value都必须是能够序列化的。

3       磁盘(DiskStore)

磁盘存储可以存储内存中驱除过来的元素,也可以在系统重启的时候将内存中的缓存信息保存起来,供系统重新启动后使用。磁盘存储是非必须的,但是使用DiskStore的时候我们需要指定一个磁盘目录来存放缓存信息。这可以在ehcache.xml文件中的ehcahce元素下的定义一个diskStore元素并指定其path属性。由diskStore元素是定义在ehcache元素下我们看出diskStore在CacheManager范围内是共享的,其是线程安全的。如果我们没有定义diskStore元素时,DiskStore会使用默认的目录作为其存储目录,该目录就是java.io.tmpdir,即Java的临时目录。当然我们也可以指定一个绝对路径。当我们指定diskStore元素的path为以下值时会被替换为实际对应的目录:

l  user.home:用户的家目录。

l  user.dir:用户的当前工作目录。

l  java.io.tmpdir:Java临时目录。

l  在命令行指定的属性,如“java -Dehcache.disk.store.dir=D:\\abc …..”。

子目录的话可以这样指定:user.home/ehcache。

此外需要注意的是因为DiskStore是把信息存放在磁盘上的,所以我们存放在磁盘上的元素必须是可以序列化的。CacheManager的DiskStore路径一旦设置好了之后将不能再更改。如果硬是更改了,那么我们的CacheManager需要基于新的路径重新建立。

3.1     指定可用容量

指定可用容量的时候我们可以在CacheManager级别通过maxBytesLocalDisk来指定。而在Cache级别我们可以通过maxBytesLocalDisk和maxEntriesLocalDisk来指定。因为DiskStore是可选的,所以这些属性也都是可选的。另外不像MemoryStore那样,我们在Cache级别上可以同时指定maxBytesLocalDisk和maxEntriesLocalDisk。如:

 <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
maxBytesLocalDisk="50G"> <diskStore path="d:\\ehcache"/> <cache name="ttt" maxBytesLocalHeap="100M" maxBytesLocalDisk="50G" maxEntriesLocalDisk="10000"/> </ehcache>

DiskStore中驱除元素跟MemoryStore中驱除元素的规则是不一样的。当往DiskStore中添加元素且此时DiskStore中的容量已经超出限制时将采用LFU(最不常用)驱除规则将对应的元素进行删除,而且该驱除规则是不可配置的。

3.2     元素过期

DiskStore中的元素过期跟MemoryStore中的元素过期是同样定义的。对于每一个Cache而言都拥有一个线程用于检查并移除其中的过期元素。至于多久检查一次,我们可以通过cache元素的diskExpiryThreadIntervalSeconds 属性来指定,默认是每两分钟检查一次。

2       非堆内存(BigMemory)

非堆内存存储是针对于企业版才有的功能,它可以不受Java GC的影响,能够创建很大的缓存。BigMemory保存的都是一个个的字节,在保存元素的时候Ehcache会对元素进行序列化再保存到BigMemory中,然后在读取的时候又会把读取到的字节进行反序列化。所以存放在其中的元素的key和value都必须是能够序列化的。

3       磁盘(DiskStore)

磁盘存储可以存储内存中驱除过来的元素,也可以在系统重启的时候将内存中的缓存信息保存起来,供系统重新启动后使用。磁盘存储是非必须的,但是使用DiskStore的时候我们需要指定一个磁盘目录来存放缓存信息。这可以在ehcache.xml文件中的ehcahce元素下的定义一个diskStore元素并指定其path属性。由diskStore元素是定义在ehcache元素下我们看出diskStore在CacheManager范围内是共享的,其是线程安全的。如果我们没有定义diskStore元素时,DiskStore会使用默认的目录作为其存储目录,该目录就是java.io.tmpdir,即Java的临时目录。当然我们也可以指定一个绝对路径。当我们指定diskStore元素的path为以下值时会被替换为实际对应的目录:

l  user.home:用户的家目录。

l  user.dir:用户的当前工作目录。

l  java.io.tmpdir:Java临时目录。

l  在命令行指定的属性,如“java -Dehcache.disk.store.dir=D:\\abc …..”。

子目录的话可以这样指定:user.home/ehcache。

此外需要注意的是因为DiskStore是把信息存放在磁盘上的,所以我们存放在磁盘上的元素必须是可以序列化的。CacheManager的DiskStore路径一旦设置好了之后将不能再更改。如果硬是更改了,那么我们的CacheManager需要基于新的路径重新建立。

3.1     指定可用容量

指定可用容量的时候我们可以在CacheManager级别通过maxBytesLocalDisk来指定。而在Cache级别我们可以通过maxBytesLocalDisk和maxEntriesLocalDisk来指定。因为DiskStore是可选的,所以这些属性也都是可选的。另外不像MemoryStore那样,我们在Cache级别上可以同时指定maxBytesLocalDisk和maxEntriesLocalDisk。如:

 <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
maxBytesLocalDisk="50G"> <diskStore path="d:\\ehcache"/> <cache name="ttt" maxBytesLocalHeap="100M" maxBytesLocalDisk="50G" maxEntriesLocalDisk="10000"/> </ehcache>

DiskStore中驱除元素跟MemoryStore中驱除元素的规则是不一样的。当往DiskStore中添加元素且此时DiskStore中的容量已经超出限制时将采用LFU(最不常用)驱除规则将对应的元素进行删除,而且该驱除规则是不可配置的。

3.2     元素过期

DiskStore中的元素过期跟MemoryStore中的元素过期是同样定义的。对于每一个Cache而言都拥有一个线程用于检查并移除其中的过期元素。至于多久检查一次,我们可以通过cache元素的diskExpiryThreadIntervalSeconds 属性来指定,默认是每两分钟检查一次。

(注:本文是基于Ehcache2.8.1所写。)

3.Ehcache中储存缓存的方式的更多相关文章

  1. Ehcache(03)——Ehcache中储存缓存的方式

    http://haohaoxuexi.iteye.com/blog/2114769 Ehcache中储存缓存的方式 目录 1     堆内存(MemoryStore) 1.1     指定可用内存 1 ...

  2. hibernate中的缓存机制

    一.为什么要用Hibernate缓存? Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数据源中的数 ...

  3. SSM-MyBatis-18:Mybatis中二级缓存和第三方Ehcache配置

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 二级缓存 Mybatis中,默认二级缓存是开启的.可以关闭. 一级缓存开启的.可以被卸载吗?不可以的.一级缓存 ...

  4. Spring Boot中的缓存支持(一)注解配置与EhCache使用

    Spring Boot中的缓存支持(一)注解配置与EhCache使用 随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决 ...

  5. SpringBoot中Shiro缓存使用Redis、Ehcache

    在SpringBoot中Shiro缓存使用Redis.Ehcache实现的两种方式实例 SpringBoot 中配置redis作为session 缓存器. 让shiro引用 本文是建立在你是使用这sh ...

  6. spring中配置缓存—ehcache

    常用的缓存工具有ehcache.memcache和redis,这里介绍spring中ehcache的配置. 1.在pom添加依赖: <!-- ehcache 相关依赖 --> <de ...

  7. mybatis中二级缓存整合ehcache实现分布式缓存

    mybatis自带二级缓存,但是这个缓存是单服务器工作,无法实现分布式缓存.那么什么是分布式缓存呢?假设现在有两个服务器1和2,用户访问的时候访问了1服务器,查询后的缓存就会放在1服务器上,假设现在有 ...

  8. (转)Ehcache作为分布式缓存的研究

    ehcache支持两种拓扑结构,一种是Distributed Caching,另一种是Replicated Caching Distributed Caching 这和一般意义上的分布式缓存非常类似, ...

  9. EhCache RMI 分布式缓存/缓存集群

    EhCache 系统简介 EhCache 是一个纯 Java 的进程内缓存框架,具有快速.精干等特点. EhCache 的主要特性有: 快速.精干 简单: 多种缓存策略: 缓存数据有两级:内存和磁盘, ...

随机推荐

  1. bzoj1069: [SCOI2007]最大土地面积 凸包+旋转卡壳求最大四边形面积

    在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大. 题解:先求出凸包,O(n)枚举旋转卡壳,O(n)枚举另一个点,求最大四边形面积 /* ...

  2. 实用性较强的idea插件

    1. .ignore 生成各种ignore文件,一键创建git ignore文件的模板,免得自己去写 2. GsonFormat 一键根据json文本生成java类  非常方便 3.Maven Hel ...

  3. HashMap1.8源码分析(红黑树)

    转载:https://segmentfault.com/a/1190000012926722?utm_source=tag-newest https://blog.csdn.net/weixin_40 ...

  4. 用 Unity 和 HTC Vive 实现高级 VR 机制(1)

    原文:Advanced VR Mechanics With Unity and the HTC Vive Part 1 作者:Eric Van de Kerckhove 译者:kmyhy VR 从来没 ...

  5. 自定义ViewPagerIndicator

    1. 简介 学习Android,自定义View不可避免,之前一直忽视这块内容,现在开始学,应该不算太晚.从常见的ViewPagerIndicator开始,当然,万能的Github上包罗万象,好用的in ...

  6. CentOS 6&7安装ffmpeg

    CentOS 6和7安装方法是不一样的,下面分别说明: 安装前都需要先安装epel扩展源 yum -y install epel-release CentOS 6比较简单,安装yum源之后直接安装即可 ...

  7. 《DSP using MATLAB》示例 Example 10.2

    代码: %% ------------------------------------------------------------------------ %% Output Info about ...

  8. Jenkins搭建windows service自动编译发布环境

    类库项目(Task)部署 前面搭建了Web站点的环境,类库项目发布不同于站点项目,它只需要将MSBuild编译出来的dll复制到目标服务器上即可,而不需要通过Web Deploy,下面来说一下如何发布 ...

  9. .Net调用Java端带有WS-Security支持的Web Service各方案实战【转】

    原文:http://www.xuebuyuan.com/641669.html 到现在为止,我们AEP平台已经发布很长一段时间了,也有很多ISV接入并上线了,就语言而言,目前主要有三类:Java..N ...

  10. IO流常规操作

    IO流 IO就是输入输出,IO设备在计算机中起着举足轻重的作用,IO流也就是输入输出流,用来交互数据,程序和程序交互,程序也可以和网络等媒介交互. 一.IO流的分类 要分类,肯定得站得不同角度来看这个 ...