内存数据库有现成的redis,高效存取键值对,键设为你的查询条件,值设为你的查询结果转为字符串
查询时先从redis取,没有再查数据库,并且设置redis的过期时间,这种方式需要项目对实时性要求不高,这样你才能用缓存,而且如果你的项目没有明显的热点,即没有某些内容确定会多次被查到,那你缓存就不会命中,添加缓存反而影响你得速度
redis是一种nosql的内存数据库,感兴趣你可以了解一下,优点就是性能强劲
数据查询请求多就把结果缓存下来,你查数据库再快也没有直接把结果从内存读出来快
同样的sql请求只有第一次查数据库,之后通通读内存
或者你干脆借助这种思想,创建一个全局的map对象,然后查询条件作key
,结果作value,就省去了了解redis的过程,把整个数据库装内存不太科学,你有多少条数据啊
2. 如何对django的model对象缓存
直接利用python提供的json包,在django model的定义中增加一个方法toJSON,利用django model 能访问 _meta.fields 得到相关属性而得到,例子如下: class Category(models.Model): autoid = models.AutoField(primary_key=True) email=models.Ch
3. 举例说明,如何为Cache对象中的缓存项设置缓存策略
没分?
你的意思是用.NET的缓存机制?
缓存一般情况下用于数据库操作的比较多.
如果此数据修改过多,不建议用缓存.一般是原始数据.其实写在程序的某固定地方作为静态变量出现我觉得也可以...
sqlServer系列有大量的索引等等操作.优化后不一定比缓存差.
同类比还有session和application.
我举个例子查询数据库的例子看和你说的是不是一回事...
string cacheKey="yourKey"; //缓存ID
object myObj= HttpContext.Current.Cache[CacheKey]; //缓存对象
if(myObj==null)
{
//证明为空,再从数据库中查询
Datatable yourTable=yourSelect();
if(yourTable==null)
return null;
else
{
HttpContext.Current.Cache.Insert(cacheKey,yourTable); //插入缓存
return yourTable;
}
}
return myObj;
4. ios怎样给tableview添加缓存
方法一:一般将服务器第一次返回的数据保存在沙盒里面。这样在手机断网的情况下可以从本地读取数据了。
1.保存到沙盒的代码:
[plain] view
plain
+ (void)saveCache:(int)type andID:(int)_id andString:(NSString *)str;
{
NSUserDefaults * setting = [NSUserDefaults standardUserDefaults];
NSString * key = [NSString stringWithFormat:@"detail-%d-%d",type, _id];
[setting setObject:str forKey:key];
[setting synchronize];
}
2.读取本地沙盒的代码
读取之前首先根据type和Id判断本地是否有
[plain] view
plain
+ (NSString *)getCache:(int)type andID:(int)_id
{
NSUserDefaults * settings = [NSUserDefaults standardUserDefaults];
NSString *key = [NSString stringWithFormat:@"detail-%d-%d",type, _id];
NSString *value = [settings objectForKey:key];
return value;
}
如果沙盒里面有数据
[plain] view
plain
NSString *value = [Tool getCache:5 andID:self.QiuTime];
if (value) {
NSDictionary *backdict = [value JSONValue];
if ([backdict objectForKey:@"items"]) {
NSArray *array=[NSArray arrayWithArray:[backdict objectForKey:@"items"]];
for (NSDictionary *qiushi in array) {
QiuShi *qs=[[[QiuShi alloc]initWithDictionary:qiushi] autorelease];
[self.list addObject:qs];
}
}
[self.tableView reloadData];
}
[self.tableView :@"数据全部加载完了.."];
self.tableView.reachedTheEnd = YES;
方法二:使用ASIHTTPRequest和ASIDownloadCache实现本地缓存
1、设置全局的Cache
在AppDelegate.h中添加一个全局变量
[plain] view plain
@interface AppDelegate : UIResponder
{
ASIDownloadCache *myCache;
}
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic,retain) ASIDownloadCache *myCache;
在AppDelegate.m中的- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中添加如下代码
[plain] view plain
//自定义缓存
ASIDownloadCache *cache = [[ASIDownloadCache alloc] init];
self.myCache = cache;
[cache release];
//设置缓存路径
NSArray *paths = (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
[self.myCache setStoragePath:[documentDirectory :@"resource"]];
[self.myCache setDefaultCachePolicy:];
在AppDelegate.m中的dealloc方法中添加如下语句
[plain] view plain
[myCache release];
到这里为止,就完成了全局变量的声明。
2、设置缓存策略
在实现ASIHTTPRequest请求的地方设置request的存储方式,代码如下
[plain] view plain
NSString *str = @"http://....../getPictureNews.aspx";
NSURL *url = [NSURL URLWithString:str];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
//获取全局变量
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
//设置缓存方式
[request setDownloadCache:appDelegate.myCache];
//设置缓存数据存储策略,这里采取的是如果无更新或无法联网就读取缓存数据
[request setCacheStoragePolicy:];
request.delegate = self;
[request startAsynchronous];
此回答请感谢:27773,是技术领域众包平台,能一对一撮合技术牛人,如果有项目合作,可以 v zhongbao27773、清理缓存数据
我在这里采用的是手动清理数据的方式,在适当的地方添加如下代码,我将清理缓存放在了应用的设置模块:
[plain] view plain
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate.myCache :];
这里清理的是这种存储策略的缓存数据,如果更换其他的参数的话,即可清理对应存储策略的缓存数据。
5. 如何使用 Windows Azure Caching
Windows Azure Caching 入门
Windows Azure Caching 提供了一种使用承载角色实例的虚拟机上的内存来进行缓存的方法。承载缓存的角色实例称为缓存群集。专用角色缓存 - 这些角色实例专用于缓存。
若要在角色实例中使用缓存,您需要配置缓存群集,然后配置缓存客户端以便它们可以访问缓存群集。
配置缓存群集
配置缓存客户端
配置缓存群集
若要配置专用角色缓存群集,请向项目中添加缓存辅助角色。
在向项目中添加缓存辅助角色后,默认配置是专用角色缓存。
在启用缓存后,可以配置缓存群集存储帐户。Windows Azure Caching 需要 Windows Azure 存储帐户。此存储帐户用于保存从组成缓存群集的所有虚拟机访问的缓存群集的相关配置数据。此存储帐户在缓存群集角色属性页的“缓存”选项卡上的“命名缓存设置”上方指定。
如果没有配置此存储帐户,则角色将无法启动。
缓存的大小由角色的 VM 大小、角色的实例计数共同决定。
本节提供了有关配置缓存大小的简单概述。有关缓存大小及其他容量规划注意事项的更多信息,请参见 Windows Azure Caching 容量规划注意事项。
若要配置虚拟机大小和角色实例数,请在“解决方案资源管理器”中右键单击角色属性,然后选择“属性”。
切换到“配置”选项卡。默认的“实例计数”为 1,默认的“VM 大小”为“小型”。
VM 大小的总内存如下:
小型:1.75 GB
中型:3.5 GB
大型:7 GB
超大型:14 GB
这些内存大小表示可用于跨 OS、缓存进程、缓存数据和应用程序共享的 VM 的内存总量。有关配置虚拟机大小的更多信息,请参见如何配置虚拟机大小。请注意,特小型 VM 大小不支持缓存。
在指定专用角色缓存后,虚拟机的所有可用内存均用于缓存。如果配置了两个角色实例,将使用虚拟机的组合内存。这构成了缓存群集,其中的可用缓存内存分布在多个角色实例上,但对缓存的客户端显示为单个资源。配置其他角色实例会以相同方式增加缓存大小。若要确定设置所需大小的缓存所需的设置,您可以使用 Windows Azure Caching 容量规划注意事项中的容量规划电子表格。
在配置缓存群集后,可以配置缓存客户端以允许访问缓存。
配置缓存客户端
若要访问 Windows Azure Caching 缓存,客户端必须位于同一部署中。如果缓存群集是专用角色缓存群集,则客户端是部署中的其他角色。提供了 NuGet 包,它可用于配置访问缓存的每个客户端角色。若要使用 Caching NuGet 包配置角色以访问缓存群集,请在“解决方案资源管理器”中右键单击角色项目,然后选择“管理 NuGet 包”。
选择“Windows Azure Caching”,单击“安装”,然后单击“我接受”。
如果“Windows Azure Caching”没有显示在列表中,请在“联机搜索”文本框中键入 WindowsAzure.Caching,然后从结果中选择它。
NuGet 包可执行多项操作:它将所需配置添加到角色的配置文件中,将缓存客户端诊断级别设置添加到 Windows Azure 应用程序的 ServiceConfiguration.cscfg 文件中,并添加所需的程序集引用。
对于 ASP.NET Web 角色,Caching NuGet 包还将两个注释掉的节添加到 web.config 中。第一个节允许会话状态存储在缓存中,第二个节启用 ASP.NET 页面输出缓存。有关更多信息,请参见如何:在缓存中存储 ASP.NET 会话状态和如何:在缓存中存储 ASP.NET 页面输出缓存。
NuGet 包将以下配置元素添加到角色的 web.config 或 app.config 中。将 dataCacheClients 节和 cacheDiagnostics 节添加到configSections 元素之下。如果 configSections 元素不存在,则会创建一个作为 configuration 元素的子级。
<configSections>
<!-- Existing sections omitted for clarity. -->
<section name="dataCacheClients"
type="Microsoft.ApplicationServer.Caching.DataCacheClientsSection, Microsoft.ApplicationServer.Caching.Core"
allowLocation="true"
allowDefinition="Everywhere" />
<section name="cacheDiagnostics"
type="Microsoft.ApplicationServer.Caching.AzureCommon., Microsoft.ApplicationServer.Caching.AzureCommon"
allowLocation="true"
allowDefinition="Everywhere" />
</configSections>
这些新节包括对 dataCacheClients 元素和 cacheDiagnostics 元素的引用。这些元素还添加到 configuration 元素中。
<dataCacheClients>
<dataCacheClient name="default">
<autoDiscover isEnabled="true" identifier="[cache cluster role name]" />
<!--<localCache isEnabled="true" sync="TimeoutBased" objectCount="100000" ttlValue="300" />-->
</dataCacheClient>
</dataCacheClients>
<cacheDiagnostics>
<crashDump mpLevel="Off" mpStorageQuotaInMB="100" />
</cacheDiagnostics>
在添加配置后,将 [cache cluster role name] 替换为承载缓存群集的角色的名称。
如果没有将 [cache cluster role name] 替换为承载缓存群集的角色的名称,则在访问缓存时会引发TargetInvocationException,其内部 DatacacheException 将显示消息“No such role exists”。
NuGet 包还将 ClientDiagnosticLevel 设置添加到 ServiceConfiguration.cscfg 中的缓存客户端角色的 ConfigurationSettings中。下面的示例是 ServiceConfiguration.cscfg 文件中的 WebRole1 节,其 ClientDiagnosticLevel 为 1,这是默认的ClientDiagnosticLevel。
<Role name="WebRole1">
<Instances count="1" />
<ConfigurationSettings>
<!-- Existing settings omitted for clarity. -->
<Setting name="Microsoft.WindowsAzure.Plugins.Caching.ClientDiagnosticLevel"
value="1" />
</ConfigurationSettings>
</Role>
Windows Azure Caching 同时提供了缓存服务器和缓存客户端诊断级别。诊断级别是配置为缓存收集的诊断信息级别的单个设置。有关更多信息,请参见解决和诊断 Windows Azure Caching 问题
NuGet 包还添加对以下程序集的引用:
Microsoft.ApplicationServer.Caching.Client.dll
Microsoft.ApplicationServer.Caching.Core.dll
Microsoft.WindowsFabric.Common.dll
Microsoft.WindowsFabric.Data.Common.dll
Microsoft.ApplicationServer.Caching.AzureCommon.dll
Microsoft.ApplicationServer.Caching.AzureClientHelper.dll
如果您的角色是 ASP.NET Web 角色,则还添加以下程序集引用:
Microsoft.Web.DistributedCache.dll。
这些程序集位于 C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\2012-10\ref\Caching\ 文件夹中。
在配置了您的客户端项目的缓存后,您可以使用以下各节中介绍的方法来使用您的缓存。
使用缓存
本节中的步骤介绍如何使用缓存执行常见任务。
如何:创建 DataCache 对象
如何:在缓存中添加和检索对象
如何:在缓存中指定对象的有效期
如何:在缓存中存储 ASP.NET 会话状态
如何:在缓存中存储 ASP.NET 页面输出缓存
如何:创建 DataCache 对象
若要以编程方式使用缓存,您需要引用该缓存。将以下代码添加到要从中使用 Windows Azure Caching 的任何文件的顶部:
using Microsoft.ApplicationServer.Caching;
如果在安装了添加必要引用的 Caching NuGet 包后,Visual Studio 仍不能识别 using 语句中的类型,请确保项目的目标配置文件是 .NET Framework 2.0 或更高版本,并确保选择没有指定客户端配置文件的配置文件之一。有关配置缓存客户端的说明,请参见配置缓存客户端。
创建 DataCache 对象有两种方法。第一种方法是仅创建 DataCache,并传入所需缓存的名称。
DataCache cache = new DataCache("default");
在实例化 DataCache 后,您可以使用它来与缓存交互,如以下各节中所述。
若要使用第二种方法,请在您的应用程序中使用默认的构造函数创建新的 DataCacheFactory 对象。这会导致缓存客户端使用配置文件中的设置。调用新的 DataCacheFactory 实例的 GetDefaultCache 方法,该方法返回 DataCache 对象,或调用 GetCache 方法并传入您的缓存的名称。这些方法返回以后可用于以编程方式访问缓存的 DataCache 对象。
// Cache client configured by settings in application configuration file.
DataCacheFactory cacheFactory = new DataCacheFactory();
DataCache cache = cacheFactory.GetDefaultCache();
// Or DataCache cache = cacheFactory.GetCache("MyCache");
// cache can now be used to add and retrieve items.
如何:在缓存中添加和检索对象
若要向缓存中添加项,可以使用 Add 或 Put 方法。Add 方法将指定的对象添加到缓存中,并按键参数的值进行键控。
// Add the string "value" to the cache, keyed by "item"
cache.Add("item", "value");
如果缓存中已存在具有相同键的对象,将引发 DataCacheException 并显示以下消息:
ErrorCode:SubStatus:An attempt is being made to create an object with a Key that already exists in the cache.Caching will only accept unique Key values for objects.
若要检索具有特定键的对象,可以使用 Get 方法。如果对象存在,则返回它,如果对象不存在,则返回 null。
// Add the string "value" to the cache, keyed by "key"
object result = cache.Get("Item");
if (result == null)
{
// "Item" not in cache. Obtain it from specified data source
// and add it.
string value = GetItemValue(...);
cache.Add("item", value);
}
else
{
// "Item" is in cache, cast result to correct type.
}
如果具有指定键的对象不存在,则 Put 方法将该对象添加到缓存中,如果该对象存在,则替换它。
// Add the string "value" to the cache, keyed by "item". If it exists,
// replace it.
cache.Put("item", "value");
如何:在缓存中指定对象的有效期
默认情况下,缓存中的项在放入缓存中 10 分钟后到期。这可在承载缓存群集的角色的角色属性中的“生存时间(分钟)”设置中进行配置。
有三种类型的“过期类型”:“无”、“绝对”和“可调窗口”。这些类型配置如何使用“生存时间(分钟)”来确定有效期。默认的“过期类型”为“绝对”,这意味着在将项放入缓存中时,记录该项有效期的倒计时器即会启动。在项经过指定的时间后,该项过期。如果指定了“可调窗口”,则在每次访问缓存中的项时,会重置该项的有效期倒计时,并且仅在自上次访问该项后经过指定的一段时间后,该项才会过期。如果指定了“无”,则“生存时间(分钟)”必须设置为“0”,并且项不会过期,只要它们在缓存中就会保持有效。
如果需要比在角色属性中配置的时间更长或更短的超时时间间隔,则可以在缓存中添加或更新项时,使用采用 TimeSpan 参数的 Add和 Put 的重载来指定特定持续时间。在下面的示例中,将字符串 value 添加到缓存中,按 item 进行键控,且超时为 30 分钟。
// Add the string "value" to the cache, keyed by "item"
cache.Add("item", "value", TimeSpan.FromMinutes(30));
若要查看缓存中的项的剩余超时时间间隔,可以使用 GetCacheItem 方法来检索 DataCacheItem 对象,该对象包含有关缓存中项的信息,其中包括剩余超时时间间隔。
// Get a DataCacheItem object that contains information about
// "item" in the cache. If there is no object keyed by "item" null
// is returned.
DataCacheItem item = cache.GetCacheItem("item");
TimeSpan timeRemaining = item.Timeout;
6. 如何使用OSCache实现对象的缓存
分页自己做吧,根据使用数据库的不同,分页方式也不同,也就是取某个区间的数据。ibatis自带的分页方法在最新版本里已经废除了。
7. C4D的对象缓存是什么来的
你好,很高兴回答你的问题,使用对象缓存可以把你想单独处理的模型提取出来在合成软件中做进一步的处理,就相当于其他3维软件中的分层渲染,希望能对你有帮助!
8. 如何使用OSCache实现对象的缓存
一、缓存对象常用API
核心Cache管理类 GeneralCacheAdministrator的常用方法
1.void putInCache(String key,Object content);//put on Object in a cache
2.Object getFromCache(String key);// get on Object from the Cache
3.void removeEntry(String key);// remove an Object in a cache
4.void flushEntry(String key);// flushes a single cache entry
5.void flushAll();// flush the entire cache immediately
6.void cancelUpdate(String key);// cacels a pending cache update
9. 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;
}
10. 如何使用Guava的缓存管理
首先,看一下使用范例:
Java代码
LoadingCache<Key,Graph> graphs =CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10,TimeUnit.MINUTES)
.removalListener(MY_LISTENER)
.build(
newCacheLoader<Key,Graph>(){
publicGraph load(Key key)throwsAnyException{
return createExpensiveGraph(key);
}
});
适用性
缓存在很多情况下都是非常有用的。比如,我们需要多次根据给定的输入获取值,而且该值计算或者获取的开销是非常昂贵的。
缓存和ConcurrentMap是非常相像的,但是它们也不完全一样。最根本的区别就是,ConcurrentMap会持有所有添加的对象,直到被显示的移除。而缓存为了限制其内存的使用,通常都会配置成可以自动的将对象移除。在某些情况下即使不自动移除对象也是非常有用的,如LoadingCache它会自动加载缓存对象。
一般,Guava缓存适用于以下几种情况:
你愿意花费一些内存来换取性能提升;
你预测到某些键会多次进行查询;
你的缓存数据不超过内存(Guava缓存是单个应用中的本地缓存。它不会将数据存储到文件中,或者外部服务器。如果不适合你,可以考虑一下 Memcached)。
如果你的需要符合上面所说的每一条,那么选择Guava缓存绝对没错。
使用CacheBuilder的构建模式可以获取一个Cache,如上面的范例所示。但是如何进行定制才是比较有趣的。
注意:如果你不需要缓存的这些特性,那么使用ConcurrentHashMap会有更好的内存效率,但是如果想基于旧有的ConcurrentMap复制实现Cache的一些特性,那么可能是非常困难或者根本不可能。
加载
对于缓存首先需要明确的是:有没有一个方法可以通过给定的键来计算/加载相应的值?如果有,那么可以使用CacheLoader。如果没有这样的方法,或者你想复写缓存的加载方式,但你仍想保留“get-if-absent-compute”语义,你可以在调用get方法时传入一个Callable实例,来达到目的。缓存的对象可以通过Cache.put直接插入,但是自动加载是首选,因为自动加载可以更加容易的判断所有缓存信息的一致性。
From a CacheLoader
LoadingCache 缓存是通过一个CacheLoader来构建缓存。创建一个CacheLoader仅需要实现V load(K key) throws Exception方法即可。下面的范例就是如何创建一个LoadingCache:
Java代码
LoadingCache<Key,Graph> graphs =CacheBuilder.newBuilder()
.maximumSize(1000)
.build(
newCacheLoader<Key,Graph>(){
publicGraph load(Key key)throwsAnyException{
return createExpensiveGraph(key);
}
});
...
try{
return graphs.get(key);
}catch(ExecutionException e){
thrownewOtherException(e.getCause());
}
通过方法get(K)可以对LoadingCache进行查询。该方法要不返回已缓存的值,要不通过CacheLoader来自动加载相应的值到缓存中。这里需要注意的是:CacheLoader可能会抛出Exception,LoaderCache.get(K)则可能会抛出ExecutionException。假如你定义的CacheLoader没有声明检查型异常,那么可以通过调用getUnchecked(K)来获取缓存值;但是一旦当CacheLoader中声明了检查型异常,则不可以调用getUnchecked。
Java代码
LoadingCache<Key,Graph> graphs =CacheBuilder.newBuilder()
.expireAfterAccess(10,TimeUnit.MINUTES)
.build(
newCacheLoader<Key,Graph>(){
publicGraph load(Key key){// no checked exception
return createExpensiveGraph(key);
}
});
...
return graphs.getUnchecked(key);
批量查询可以使用getAll(Iterable<? extends K>)方法。缺省,getAll方法将循环每一个键调用CacheLoader.load方法获取缓存值。当缓存对象的批量获取比单独获取更有效时,可以通过复写CacheLoader.loadAll方法实现缓存对象的加载。此时当调用getAll(Iterable)方法时性能也会提升。
需要注意的是CacheLoader.loadAll的实现可以为没有明确要求的键加载缓存值。比如,当为某组中的一些键进行计算时,loadAll方法则可能会同时加载组中其余键的值。
From a Callable
所有Guava缓存,不论是否会自动加载,都支持get(K, Callable(V))方法。当给定键的缓存值已存在时则直接返回,否则通过指定的Callable方法进行计算并将值存放到缓存中。直到加载完成时,相应的缓存才会被更改。该方法简单实现了"if cached, return; otherwise create, cache and return"语义。
Java代码
Cache<Key,Value> cache =CacheBuilder.newBuilder()
.maximumSize(1000)
.build();// look Ma, no CacheLoader
...
try{
// If the key wasn't in the "easy to compute" group, we need to
// do things the hard way.
cache.get(key,newCallable<Value>(){
@Override
publicValue call()throwsAnyException{
return doThingsTheHardWay(key);
}
});
}catch(ExecutionException e){
thrownewOtherException(e.getCause());
}
直接插入
使用cache.put(key, value)方法可以将值直接插入到缓存中,但这将会覆盖缓存中已存在的值。通过使用Cache.asMap()所导出的ConcurrentMap对象中的方法也可以对缓存进行修改。但是,请注意asMap中的任何方法都不能自动的将数据加载到缓存中。也就是说,asMap中的各方法是在缓存自动加载范围之外来运作。所以,当你使用CacheLoader或Callable来加载缓存时,应该优先使用Cache.get(K, Callable<V>),而不是Cache.asMap().putIfAbsent。
缓存回收
残酷的现实是我们可以肯定的说我们没有足够的内存来缓存一切。你必须来决定:什么时候缓存值不再值得保留?Guava提供了三种基本的缓存回收策略:基于容量回收策略,基于时间回收策略,基于引用回收策略。
基于容量回收策略
使用CacheBuilder.maximumSize(long)可以设置缓存的最大容量。缓存将会尝试回收最近没有使用,或者没有经常使用的缓存项。警告:缓存可能会在容量达到限制之前执行回收,通常是在缓存大小逼近限制大小时。
另外,如果不同的缓存项有不同的“权重”, 如,缓存项有不同的内存占用,此时你需要使用CacheBuilder.weigher(Weigher)指定一个权重计算函数,并使用CacheBuilder.maxmumWeight(long)设定总权重。和maximumSize同样需要注意的是缓存也是在逼近总权重的时候进行回收处理。此外,缓存项的权重是在创建时进行计算,此后不再改变。
Java代码
LoadingCache<Key,Graph> graphs =CacheBuilder.newBuilder()
.maximumWeight(100000)
.weigher(
newWeigher<Key,Graph>(){
publicint weigh(Key k,Graph g){
return g.vertices().size();
}
})
.build(
newCacheLoader<Key,Graph>(){
publicGraph load(Key key){// no checked exception
return createExpensiveGraph(key);
}
});
基于时间回收策略
CacheBuilder为基于时间的回收提供了两种方式:
expireAfterAccess(long, TimeUnit) 当缓存项在指定的时间段内没有被读或写就会被回收。这种回收策略类似于基于容量回收策略;
expireAfterWrite(long, TimeUnit) 当缓存项在指定的时间段内没有更新就会被回收。如果我们认为缓存数据在一段时间后数据不再可用,那么可以使用该种策略。
就如下面的讨论,定时过期回收会在写的过程中周期执行,偶尔也会读的过程中执行。
测试定时回收
测试定时回收其实不需要那么痛苦的,我们不必非得花费2秒来测试一个2秒的过期。在构建缓存时使用Ticker接口,并通过CacheBuilder.ticker(Ticker)方法指定时间源,这样我们就不用傻乎乎等系统时钟慢慢的走了。
基于引用回收策略
通过键或缓存值的弱引用(weak references),或者缓存值的软引用(soft references),Guava可以将缓存设置为允许垃圾回收。
CacheBuilder.weakKeys() 使用弱引用存储键。当没有(强或软)引用到该键时,相应的缓存项将可以被垃圾回收。由于垃圾回收是依赖==进行判断,因此这样会导致整个缓存也会使用==来比较键的相等性,而不是使用equals();
CacheBuilder.weakValues() 使用弱引用存储缓存值。当没有(强或软)引用到该缓存项时,将可以被垃圾回收。由于垃圾回收是依赖==进行判断,因此这样会导致整个缓存也会使用==来比较缓存值的相等性,而不是使用equals();
CacheBuilder.softValues() 使用软引用存储缓存值。当响应需要时,软引用才会被垃圾回收通过最少使用原则回收掉。由于使用软引用造成性能上的影响,我们强烈建议使用可被预言的maximum cache size的策略来代替。同样使用softValues()缓存值的比较也是使用==,而不是equals()。
显示移除
在任何时候,你都可以可以通过下面的方法显式将无效的缓存移除,而不是被动等待被回收:
使用Cache.invalidate(key)单个移除;
使用Cache.invalidteAll(keys)批量移除;
使用Cache.invalidateAll()移除全部。