【本地缓存】
先来看几个问题
- 本地缓存会被垃圾回收器回收吗?
- 本地缓存会造成服务器内存告急吗?
缓存并不陌生,最常用的缓存服务器当属redis。那么特殊环境下用不了redis时怎么办呢?
那只能用本地缓存了。别忘了利用jvm虚拟机的内存呀。
定义一个缓存场景
- 假设一个热点数据的场景,南京老门东前一天的人流量及区域分布
private static final Map<String, String> HEAT_DATA = Maps.newHashMap();
public static void main(String[] args) {
HEAT_DATA.put("num", "5000");
HEAT_DATA.put("A", "2500");
HEAT_DATA.put("B", "2500");
System.out.println(HEAT_DATA);
}
- 上面是最基本的方式,利用全局变量Map的形式,这种方式的弊端就是如果KEY不确定的话容易造成垃圾数据,从而侵占内存,最终导致OOM;但如果KEY是确定的,这种方式也是可取的
public static void main(String[] args) throws ExecutionException {
LoadingCache<String, String> graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(
new CacheLoader<String, String>() {
@Override
public String load(String key) {
return createExpensiveGraph(key);
}
private String createExpensiveGraph(String key) {
return "不存在的缓存key: ".concat(key);
}
});
graphs.put("num", "5000");
graphs.put("A", "2500");
graphs.put("B", "2500");
String num = graphs.get("num");
String A = graphs.get("A");
String B = graphs.get("B");
System.out.println(num);
System.out.println(A);
System.out.println(B);
}
- 上面是利用guava库的缓存,好处是可以定义最大缓存数量和缓存过期时间。
- 再回顾下最开始说的问题,本地缓存会被回收吗?答案是否定的,定义了缓存那么一定会有方法来访问它,我们说的垃圾回收机制算法一个是可达性分析法,一个是引用计数法,既然有方法访问它,那么我想它一定满足上面说的两种算法。那么本地缓存会造成服务器内存告急吗?我想除非大量的存较大的对象,一般来说是不会的,当然了,还要看具体的情况,比如给定jvm虚拟机内存大小还有缓存中到底存多少对象,这个是要实际测试的,不是嘴上说说就能知道的。