前言
缓存大家肯定都用过或者接触过,缓存实现也有很多种。这里就说一下基于jvm的缓存,这种缓存一般在web系统、比较传统的系统中用得比较多。经常在系统启动之后,去加载特定的数据(比如组织机构等),并且存放形式直接放到jvm中,没有使用中间件去存放的情况。
不推荐的实现方式
存放缓存的对象,使用的强引用;下面写出伪代码
public static Map<String,String> cachMap = new HashMap();
//项目启动就把数据加载到缓存中
@PostConstuct
public void initCachMap(){
//将数据放到HashMap中做为缓存
cachMap.putAll(getDataMap());
}
类似的这种实现我看到过很多次,这种方式如果在系统中大量的使用,会长时间占用系统的内存,一旦缓存中的数据过多,容易发生oom(我也遇到过)
使用Soft Reference解决这个问题
// 创建一个SoftReference
SoftReference<Map<String, String>> softReference = new SoftReference<>(new HashMap<>());
@PostConstuct
public void initCachMap(){
//将数据放到HashMap中做为缓存
Map<String,String> cachMap = softReference.get();
cachMap.putAll(getDataMap());
}
这样就把强引用改成了软引用,在系统内存不足时候,发生GC时对象就会被回收掉,减少系统oom的机率。
小结
Java中一共有四种引用类型,它们分别是强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。这四种引用类型的强度逐渐减弱。在开发中除了强引用,软引用也是有引用场景的。
-
强引用(Strong Reference):
- 强引用是最常见的引用类型。
- 只要强引用存在,垃圾回收器就不会回收被引用的对象。
- 当内存不足时,即使抛出OutOfMemoryError,也不会回收具有强引用的对象。
-
软引用(Soft Reference):
- 软引用用于描述一些非必需但仍有用的对象。
- 在内存足够时,软引用对象不会被回收。
- 只有在内存不足时,系统才会回收软引用对象。
- 常用于实现缓存技术,如网页缓存、图片缓存等。
-
弱引用(Weak Reference):
- 弱引用的引用强度比软引用更弱。
- 无论内存是否足够,只要垃圾回收器开始进行垃圾回收,被弱引用关联的对象都会被回收。
-
虚引用(Phantom Reference):
- 虚引用是最弱的引用类型。
- 如果一个对象仅持有虚引用,那么它和没有任何引用一样,随时可能被回收。