转自: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. Java中处理异常的9个最佳实践

    Java中的异常处理不是一个简单的话题.初学者很难理解,甚至有经验的开发人员也会花几个小时来讨论应该如何抛出或处理这些异常. 这就是为什么大多数开发团队都有自己的异常处理的规则和方法.如果你是一个团队 ...

  2. 前端jsp页面script引入url项目名使用${appName}

    <script src="/${appName}/commons/jslib/CommonValue.js"></script> 新建一个com.autum ...

  3. HDU 5816 状压DP&排列组合

    ---恢复内容开始--- Hearthstone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java ...

  4. java 实现断点续传

    请求头一:>>>>>>>>>>>>>>>>>>>>>>>> ...

  5. facebook开源的prophet时间序列预测工具---识别多种周期性、趋势性(线性,logistic)、节假日效应,以及部分异常值

    简单使用 代码如下 这是官网的quickstart的内容,csv文件也可以下到,这个入门以后后面调试加入其它参数就很简单了. import pandas as pd import numpy as n ...

  6. Android 五种存储方式个人总结

    一 . 文件存储 FileOutputStream out = openFileOutput("data",Context.MODE_PRIVATE); BufferedWrite ...

  7. delphi7完全关闭一个窗体

    如果一个工程中有若干个form,在程序运行中若要彻底关闭其中的一个窗体 除了点击右上角的小叉叉外,也可以在form的close事件中添加一句话 procedure TLockScreen.FormCl ...

  8. 关于面向对象和String类型的 09,10

    package test.面试题; public class Test9 { public static void main(String[] args){ Outer.Inner in=new Ou ...

  9. 公式中表达单个双引号【"】和空值【""】的方法及说明

    http://club.excelhome.net/thread-661904-1-1.html 有人问为什么不用三个双引号"""来表示单个双引号["]呢,如果 ...

  10. Relation.js——基于pixi.js的拓展模块之人物关系图谱

    出于[重构基于D3的关系图谱项目]的目的,在看完pixi.js之后,并且网上又没有现成的基于webgl的关系图谱js库,于是,本人决定自己写一个. 因为平常要工作的原因,进度可能有点慢,但是githu ...