Guava 规避OOM需要注意的点

gvaua cache 使用堆内存,因此使用不当会出现OOM问题

保持上限
private static Cache cache = CacheBuilder.newBuilder().maximumSize(5).build();

public static void main(String[] args) {
    for (int i = 0; i < 10; i++) {
        cache.put(String.valueOf(i), i);
    }
    System.out.println(cache.asMap());
}

输出结果

{6=6, 9=9, 8=8, 7=7, 5=5}
设置有效期
// 当写入速度大于失效速度时,会OOM,因此应同时设置上限
private static Cache cache = CacheBuilder.newBuilder().expireAfterWrite(2, TimeUnit.SECONDS).build();

public static void main(String[] args) throws InterruptedException {
    for (int i = 0; i < 10; i++) {
        cache.put(String.valueOf(i), i);
    }
    Thread.sleep(3000);
    System.out.println(cache.asMap());
}

输出结果

{}
设置冷数据有效期
// 当写入速度大于失效速度时,会OOM,因此应同时设置上限
private static Cache cache = CacheBuilder.newBuilder().expireAfterAccess(2, TimeUnit.SECONDS).build();

public static void main(String[] args) throws InterruptedException {
    for (int i = 0; i < 10; i++) {
        cache.put(String.valueOf(i), i);
    }
    Thread.sleep(1000);
    cache.getIfPresent("5");
    Thread.sleep(1000);
    System.out.println(cache.asMap());
}

输出结果

{5=5}
设置引用规则
private static Cache cache = CacheBuilder.newBuilder().build();

public static void main(String[] args) throws InterruptedException {
    while (true) {
        cache.put(UUID.randomUUID().toString(), new String());
    }
}

输出结果

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.nio.CharBuffer.wrap(CharBuffer.java:373)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:265)

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

调整后则不会OOM

private static Cache cache = CacheBuilder.newBuilder().weakKeys().build();

CacheBuilder.weakKeys():使用弱引用存储键。当键没有其它(强或软)引用时,缓存项可以被垃圾回收。

CacheBuilder.weakValues():使用弱引用存储值。当值没有其它(强或软)引用时,缓存项可以被垃圾回收。

CacheBuilder.softValues():使用软引用存储值。软引用只有在响应内存需要时,才按照全局最近最少使用的顺序回收。

你可能感兴趣的:(java)