问题描述:
SEOURL 跳转地址的cache。利用map key(SeoCacheKey) value(url)的方式缓存,以每2小时策略和Entry<15000条策略,以及Memery<?策略更新缓存。由于key的设计过于粗狂,导致
key在缓存中占用太多内存,且key中的核心property生命周期过长,导致失真。
解决方案:
利用WeakReference弱引用,管理最初的核心property,使之成为一个真实的,不会导致memery膨胀的object。
代码如下,无需关注其他内容,最重要的是弱引用的实现和使用
public class SeoCacheKey {
private static ReferenceQueue<RepositoryItem> PREFERENCEQUEUE = new ReferenceQueue<RepositoryItem>();
WeakReference<RepositoryItem> mRepositoryItemReference;
Repository mRepository;
public SeoCacheKey(UrlTemplate pUrlTemplate, RepositoryItem pRepositoryItem, String pContextRoot) {
this.mRepository = pRepositoryItem.getRepository();
//弱引用管理此核心property对象
this.mRepositoryItemReference = new WeakReference<RepositoryItem>(pRepositoryItem, PREFERENCEQUEUE);
}
//由于使用时存在多线程,同步此方法,确保换取后对象在生命周期内的唯一性
public synchronized RepositoryItem getRepositoryItem(){
RepositoryItem item = this.mRepositoryItemReference.get();
if(item == null){
if (StringUtil.empty(mItemID)) {
throw (new IllegalArgumentException("The parameter \"mItemID\" can not be empty."));
}
if (StringUtil.empty(mItemDescriptorName)) {
throw (new IllegalArgumentException("The parameter \"mItemDescriptorName\" can not be empty."));
}
try {
item = mRepository.getItem(mItemID, mItemDescriptorName);
} catch (RepositoryException e) {
throw (new CustomRepositoryException("Can not get repository item whose id is " + mItemID + " and descriptor name is "
+ mItemDescriptorName + ".", e));
}
}
return item;
}
}
关于java的强引用,软引用,弱引用,虚引用请google一把
如在工作中遇到需要做缓存的地儿,请不要忘记java中除了强引用(导致OutOfMemeryException)外,还有可爱的软引用,弱引用,以及可以监视对象被回收的虚引用。
对这个知识点的扩展之原子引用以确保原子性
public class SeoCacheKey {
//原子引用
AtomicReference<WeakReference<RepositoryItem>> mAtomicReference;
WeakReference<RepositoryItem> mRepositoryItemReference;
UrlTemplate urlTemplate;
Repository mRepository;
String mRepositoryName;
String mItemDescriptorName;
String mItemID;
String contextRoot;
public SeoCacheKey(UrlTemplate pUrlTemplate, RepositoryItem pRepositoryItem, String pContextRoot) {
this.urlTemplate = pUrlTemplate;
this.mRepository = pRepositoryItem.getRepository();
this.mRepositoryName = pRepositoryItem.getRepository().getRepositoryName();
try {
this.mItemDescriptorName = pRepositoryItem.getItemDescriptor().getItemDescriptorName();
} catch (RepositoryException e) {
throw new IllegalArgumentException("Get item descriptor name error!",e);
}
this.mItemID = pRepositoryItem.getRepositoryId();
this.contextRoot = pContextRoot;
WeakReference<RepositoryItem> repositoryItemReference = generateWeakReference(pRepositoryItem);
this.mAtomicReference = new AtomicReference<WeakReference<RepositoryItem>>(repositoryItemReference);
}
public RepositoryItem getRepositoryItem() {
RepositoryItem item = this.mAtomicReference.get().get();
if (item != null) {
return item;
}
if (StringUtil.empty(mItemID)) {
throw (new IllegalArgumentException(
"The parameter \"mItemID\" can not be empty."));
}
if (StringUtil.empty(mItemDescriptorName)) {
throw (new IllegalArgumentException(
"The parameter \"mItemDescriptorName\" can not be empty."));
}
try {
item = mRepository.getItem(mItemID, mItemDescriptorName);
WeakReference<RepositoryItem> repositoryItemReference = generateWeakReference(item);
//确保了对象的原子性,使得其他线程在调用的这个类的时候,不会出现doublechecking的尴尬
//关于doublechecking,请google。或参看http://spice.iteye.com/blog/1117370
this.mAtomicReference.getAndSet(repositoryItemReference);
return item;
} catch (RepositoryException e) {
throw (new CustomRepositoryException(
"Can not get repository item whose id is " + mItemID
+ " and descriptor name is " + mItemDescriptorName
+ ".", e));
}
}
private WeakReference<RepositoryItem> generateWeakReference(
RepositoryItem item) {
ReferenceQueue<RepositoryItem> referenceQueue = new ReferenceQueue<RepositoryItem>();
WeakReference<RepositoryItem> repositoryItemReference = new WeakReference<RepositoryItem>(
item, referenceQueue);
return repositoryItemReference;
}
}
分享到:
相关推荐
弱引用的应用场景有很多,例如,在缓存机制中,我们可以使用弱引用来缓存对象,以便在内存紧张时释放这些对象。在图片处理中,我们可以使用弱引用来缓存图片,以便在内存紧张时释放这些图片。 弱引用是一种非常有用...
Java中的弱引用编程开发技术是Java内存管理的一个重要概念,对于优化内存使用和防止内存泄漏具有关键作用。本文将深入探讨这一主题,帮助你在这十分钟内建立起对弱引用的理解。 首先,我们需要知道Java的内存区域...
### Java中的软引用、弱引用和虚引用详解 #### 一、引言 在Java开发过程中,特别是Android应用开发中,经常会遇到一个普遍的问题——内存溢出(OutOfMemory Error,简称OOM)。这个问题往往与如何有效地管理内存...
在本文中,我们将深入探讨Java缓存的简单应用,并结合给出的资源——“JAVA的缓存应用.ppt”来进行讨论。 首先,让我们了解什么是缓存。缓存是计算机系统中用于临时存储数据的快速访问区域,目的是减少从主存储器或...
2. **软引用**:使用Java的`SoftReference`可以创建一个弱化的缓存,这样在内存紧张时,JVM会自动回收这些不再使用的反射对象,以释放内存。 ```java public class ReflectionUtil { private static Map, ...
标题中的“websphere缓存java调用以及jar包”指的是在IBM WebSphere Application Server (WAS) 中使用Java编程方式来管理和操作缓存系统。WebSphere应用服务器提供了一种高效的方式来存储和检索频繁访问的数据,以...
综上所述,Java中的四种引用类型按照引用强度由高到低依次是强引用、软引用、弱引用和虚引用。每种引用都有其适用场景: - **强引用**:用于保持对象的生命周期,确保对象不被垃圾回收。 - **软引用**:用于实现内存...
Ehcache支持内存和磁盘缓存,提供对象过期策略,并且可以很容易地集成到各种Java应用中。 Java Caching System (JCS)是Apache Turbine的一个子项目,提供复合缓存功能,对象可以被缓存到内存和硬盘,并支持对象过期...
在这个过程中,软引用(Soft Reference)和弱引用(Weak Reference)是两种非常重要的工具,它们可以帮助我们避免内存泄漏,提高应用的内存效率。下面我们将深入探讨这两种引用类型及其在Android中的应用。 首先,...
弱引用主要用于实现较弱的引用关系,如缓存中的元素。 **示例代码**: ```java String str = new String("hello"); ReferenceQueue<String> queue = new ReferenceQueue(); WeakReference<String> weakRef = new ...
在Java中,为了更好地管理对象的生命周期,从JDK 1.2开始引入了四种不同级别的引用类型:强引用、软引用、弱引用和虚引用。每种引用类型都有其特定的应用场景,通过灵活运用这些引用类型,开发者可以在内存管理和...
这里的“软引用”是指Java中的软引用,它是一种弱化的引用,即使有软引用指向对象,只要发生垃圾回收并且内存不足,软引用的对象仍然会被回收。在磁盘缓存中,软引用可以防止图片在内存不足时立即被清理,但又允许在...
因此,在获取弱引用对象的代码中,一定要判断是否为null,以免出现NullPointerException异常导致应用崩溃。 弱引用对象的生命周期可以通过WeakReferenceTest类来了解。该类中,我们创建了一个弱引用对象,并将其...
Java 缓存技术在开发高效率、高性能的应用程序时起着至关重要的作用。SimpleCache 是一个基于 Java 的轻量级缓存工具,旨在提供简单易用的缓存解决方案。在这个 SimpleCache.zip 压缩包中,包含的是 SimpleCache 库...
Java中的弱引用是一种特殊的引用类型,它允许程序员创建对对象的引用,但这些引用不会阻止对象被垃圾收集器回收。这种引用的引入主要是为了解决内存管理和缓存策略中的问题,尤其是在防止内存泄漏方面。 首先,我们...
【Java缓存工具 SimpleCache】是一个实用的Java编程示例,它展示了如何在应用程序中实现一个简单的缓存机制。在软件开发中,缓存是一种优化技术,用于存储频繁访问的数据,以便快速检索,减少对主数据库或其他计算...
当缓存大小成为问题时,可以通过调整缓存策略(如使用弱引用、软引用或计算对象的引用强度)来减少内存占用。同时,及时释放不再使用的对象,防止内存泄漏,也是提升系统稳定性和效率的重要手段。 总的来说,理解...
Java中的四种引用类型是Java内存管理的重要组成部分,它们分别是强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)。每种引用类型具有不同的特点和用途,...
本篇文章将深入探讨软引用在缓存中的应用以及其工作原理。 软引用是Java中的一个特殊引用类型,它表示一个弱化的引用,介于强引用和弱引用之间。强引用是默认的引用类型,只要对象被强引用指向,就不会被垃圾收集器...