缓存对象
1、TreeCache / JBossCache
JBossCache是一个复制的事务处理缓存,它允许你缓存企业级应用数据来更好的改善性能。缓存数据被自动复制,让你轻松进行JBoss服务器之间 的集群工作。JBossCache能够通过JBoss应用服务或其他J2EE容器来运行一个MBean服务,当然,它也能独立运行。
2、WhirlyCache
Whirlycache是一个快速的、可配置的、存在于内存中的对象的缓存。它能够通过缓存对象来加快网站或应用程序的速度,否则就必须通过查询数据库或其他代价较高的处理程序来建立。
3、SwarmCache
SwarmCache是一个简单且有效的分布式缓存,它使用IP multicast与同一个局域网的其他主机进行通讯,是特别为集群和数据驱动web应用程序而设计的。SwarmCache能够让典型的读操作大大超过写操作的这类应用提供更好的性能支持。
4、JCache
JCache是个开源程序,正在努力成为JSR-107开源规范,JSR-107规范已经很多年没改变了。这个版本仍然是构建在最初的功能定义上。
5、ShiftOne
ShiftOne Java Object Cache是一个执行一系列严格的对象缓存策略的Java lib,就像一个轻量级的配置缓存工作状态的框架。
② android 中怎么缓存一个对象
写入文件上也可以,你在sd卡上创建一个文件,写入其中也是可以的,这样还可以保存好数据。如果写入缓存中也不是不行但是如果忽然关机啥的程序退出,或者有其他程序调用缓存的就可能出错,所以如果不是必须的话不要直接存入缓存中。还有就是如果数据十分小就几个字符串或数字啥的我想你也知道应该放到sharedpreferences中。
③ Spring如何配置数据库查询缓存/对象缓存EHCache
在ehcache.xml文件中配置查询缓存参数,ehcache.xml文件配置如下:
<ehcache>
<!--diskStore元素,配置一个目录,这个目录用来存放数据,
也就是说,如果EhCache需要把数据写入磁盘,将会写到这个目录下-->
<diskStorepath="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskPersistent="false"
="120"/>
<cachename="ehcacheName"
maxElementsInMemory="3000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="36000"
overflowToDisk="true"
/>
</ehcache>
2. spring的配置
第一步:给指定方法配置缓存/src/main/resources/applicationContext-resources.xml
<ehcache:proxyid="userGroupServiceProxy"refId="userGroupService">
<ehcache:cachingcacheName="cash15Min"methodName=""/>
<ehcache:cachingcacheName="cash15Min"methodName=""/>
<ehcache:cachingcacheName="cash15Min"methodName="selectuserGroupById"/>
</ehcache:proxy>
配置参数的含义如下:
id:唯一标识符
refId:需要配置缓存的service或者controller
cacheName:缓存名称
methodName:需要缓存的方法,这个方法必须是shoppingHomeService中的方法
第二步:在控制器中注入依赖的缓存userGroupServiceProxy /src/main/webapp/WEB-INF/dispatcher-servlet.xml
<beanid="PFController"class="com.java.mall.controller.PFController">
<propertyname="userService"ref="userService"></property>
<propertyname="userGroupService"ref="userGroupServiceProxy"></property>
</bean>
同时需要在实体类中注入依赖,提供setter方法,
;
publicvoidsetuserGroupService(){
this.userGroupService=userGroupService;
}
④ 谈谈RecyclerView中的缓存
Android深入理解RecyclerView的缓存机制
RecyclerView在项目中的使用已经很普遍了,可以说是项目中最高频使用的一个控件了。除了布局灵活性、丰富的动画,RecyclerView还有优秀的缓存机制,本文尝试通过源码深入了解一下RecyclerView中的缓存机制。
RecyclerView做性能优化要说复杂也复杂,比如说布局优化,缓存,预加载等等。其优化的点很多,在这些看似独立的点之间,其实存在一个枢纽:Adapter。因为所有的ViewHolder的创建和内容的绑定都需要经过Adaper的两个函数onCreateViewHolder和onBindViewHolder。
因此我们性能优化的本质就是要减少这两个函数的调用时间和调用的次数。如果我们想对RecyclerView做性能优化,必须清楚的了解到我们的每一步操作背后,onCreateViewHolder和onBindViewHolder调用了多少次。因此,了解RecyclerView的缓存机制是RecyclerView性能优化的基础。
为了理解缓存的应用场景,本文首先会简单介绍一下RecyclerView的绘制原理,然后再分析其缓存实现原理。
RecyclerView滑动时会触发onTouchEvent#onMove,回收及复用ViewHolder在这里就会开始。我们知道设置RecyclerView时需要设置LayoutManager,LayoutManager负责RecyclerView的布局,包含对ItemView的获取与复用。以LinearLayoutManager为例,当RecyclerView重新布局时会依次执行下面几个方法:
上述的整个调用链:onLayoutChildren()->fill()->layoutChunk()->next()->getViewForPosition(),getViewForPosition()即是是从RecyclerView的回收机制实现类Recycler中获取合适的View,下面主要就来从看这个Recycler#getViewForPosition()的实现。
上述逻辑用流程图表示:
RecyclerView在Recyler里面实现ViewHolder的缓存,Recycler里面的实现缓存的主要包含以下5个对象:
public final class Recycler {
final ArrayList mAttachedScrap = new ArrayList<>();
ArrayList mChangedScrap = null;
RecyclerView在设计的时候讲上述5个缓存对象分为了3级。每次创建ViewHolder的时候,会按照优先级依次查询缓存创建ViewHolder。每次讲ViewHolder缓存到Recycler缓存的时候,也会按照优先级依次缓存进去。三级缓存分别是:
使用自定义ViewCacheExtension后,view离屏后再回来不会走onBindViewHolder()方法。
holder.setIsRecyclable(false),这样的话每次都会走onCreateViewHolder()和onBindViewHolder()方法
1.提前初始化viewHolder,放到缓存池中
viewPool.putRecycledView(adapter.onCreateViewHolder(recyclerView, 1))
2.提前初始化view,在onCreateViewHolder的时候去取view
3.自定义ViewCacheExtension
4.适当的增加cacheSize
4.公用缓存池,比如多个viewPager+fragment场景使用,或者全局单利缓存池,感觉用户不大。
有2中做法有值
第一种
第二种
不会,因为prefetch(GapWorker中的一个方法)之后mViewCacheMax会变成mRequestedCacheMax + extraCache
有2种方式可以让缓存失效
第一种
recyclerView.setItemViewCacheSize(-1)
第二种
recyclerView.setItemViewCacheSize(0)
layoutManager.isItemPrefetchEnabled = false
设置不缓存后,来回滑动让view进入屏幕离开屏幕,viewHolder的item时会多次走onBindViewHolder()方法。
⑤ MySQL表对象缓存
表对象缓存: 是将某个表对象的字典信息(定义内容)缓存到内存中,用来提高对表的访问效率。某个表被访问过一次后,只要服务器没有关闭且表定义没有被修改的条件下,访问该表,只需要从内存中找到这个已经缓存起来的对象做相应操作即可。
用户访问表时,表对象在缓存时: 通过HASH算法找到TABLE_SHARE,然后每个线程构造各自的实例化TABLE即可。
用户访问表时,当表没有被缓存的情况下: 第一需要打开表,首先需要从系统表中将这个表的所有信息都读入内存中,这些信息包括表名、库名、所有列信息、列的默认值、表的字符集、对应的frm文件路径、所属存储引擎、主键等,将这些信息构造一个TABLE_SHARE结构体,这个结构体是表对象缓存的第一层,所有用户共享访问且为静态不允许修改,它是缓存在table_def_cache(由参数table_definition_cache控制)中的。
而真正与用户打交道的是TABLE_SHARE的衍生品,它对应结构体为TABLE,在被使用前需要将TABLE_SHARE结构体实例化TABLE才能被使用,由每个线程构造各自的实例化TABLE即可。(实例化的TABLE由table_open_cache及table_open_cache_instance控制)
注意1: DDL操作时会将所有instance锁住,而DML操作时instance之间互不干扰。
(DDL statements still require a lock on the entire cache, but such statements are much less frequent than DML statements.)
注意2: 一个线程中如果打开表过多,超过一个instance限制的大小时,是不能跨instance缓存的
(instance大小:table_open_cache / table_open_cache_instances)
表缓存涉及其他参数: 通过下面参数判断table_open_cache参数设置是否合理
table_open_cache_hit:能够从table open cache的free list中找到table则为命中,+1
table_open_cache_misses:与table_open_cache_hit相反,如果找不到则需要重新实例化则+1,通常发生在初始化第一次加载表或超过table_open_cache的设置被淘汰后需要重新实例化。
table_open_cache_overflow:table cache淘汰的数量,每次淘汰+1
opened_tables:已经打开的表数。如果Opened_tables很大,那么table_open_cache的值可能太小了。
open_tables:总的instance (table cache)的总数