간단한 Java 인 메모리 캐시를 찾고 있습니다.


102

동시성이 좋고 (LinkedHashMap은 충분하지 않음) 주기적으로 디스크에 직렬화 할 수있는 간단한 Java 메모리 내 캐시를 찾고 있습니다.

내가 필요하지만 찾기 힘든 것으로 판명 된 한 가지 기능은 물체를 "점검"하는 방법입니다. 즉, 캐시가 그렇지 않은 경우보다 오랫동안 개체를 유지하지 않고 캐시에서 개체를 검색합니다.

최신 정보: 언급하지 않은 추가 요구 사항은 캐시 된 개체 (플로트 배열 포함)를 제자리에서 수정할 수 있어야한다는 것입니다.

누구든지 권장 사항을 제공 할 수 있습니까?


1
나는 "공정 내"와 더 가벼운 무게와 비슷한 것을 찾고있다. 힙의 Eclipse 플러그인 내에 일부 데이터를 저장하는 데 사용하고 싶습니다. Ehcache와 JCS는 내 취향에 비해 너무 무겁고 / 분산 된 / J2EE처럼 보입니다.
Uri


Apache Ignite ( ignite.apache.org )를 추천합니다
Bhagat S.

1
이 질문은 종결되었고 (사실 6 년 후) 오늘날 사람들이 여전히 궁금해하는 점은 SO의 중재자 시스템이 어떻게 실패하고 있는지 보여줍니다.
dustinevan

답변:


61

이 질문이 처음에 제기 되었으므로 Google의 Guava 라이브러리 에는 이제 강력하고 유연한 캐시가 포함됩니다. 나는 이것을 사용하는 것이 좋습니다.


3
Spring은 더 이상 Guava 캐시를 지원하지 않습니다 : stackoverflow.com/questions/44175085/…
sinner

@sanity는 Jcache를 구현합니까?
Gaurav

Caffine 은 또한 훌륭하고 성능이 뛰어난 캐싱 라이브러리입니다. Caffeine은 Java 8을 기반으로하는 고성능에 가까운 최적의 캐싱 라이브러리입니다. Caffeine은 Google Guava에서 영감을받은 API를 사용하여 메모리 내 캐시를 제공합니다
Slavus

37

Ehcache 는 이에 대한 꽤 좋은 솔루션이며 유휴 타임 스탬프를 업데이트하지 않도록 엿볼 수있는 방법이 있습니다 ( getQuiet () 가 메서드입니다). 내부적으로 Ehcache는 ConcurrentHashMap과 같은 맵 세트로 구현되므로 유사한 종류의 동시성 이점이 있습니다.


2
감사합니다. 추가 질문 : EHcache (예 : 배열)에서 개체를 검색하고 수정하면 개체가 캐시에서 업데이트됩니까? 즉. EHCache가 객체에 대한 참조를 유지하고 있습니까?
sanity

1
나는 그렇게 믿는다. 그러나 이것을 안전하게하기 위해서는 당연히 객체를 적절히 잠 가야한다.
Alex Miller

나는 ehcache를 좋아하지만 10mb 항아리입니다. 너무 큽니다.
markthegrea

23

간단한 것이 필요하다면 이것이 계산서에 맞을까요?

Map<K, V> myCache = Collections.synchronizedMap(new WeakHashMap<K, V>());

디스크에 저장되지는 ​​않지만 간단하게 원한다고 말씀하셨습니다.

연결:

(Adam이 말했듯이,지도를 동기화하면 성능이 저하됩니다. 아이디어에 머리카락이 없다는 말은 아니지만 빠르고 더러운 솔루션으로 충분합니다.)


4
거대한지도 전체를 동기화하는 것은 엄청난 불이익입니다. 약한 유형을 동시 해시 맵에 쉽게 저장하고 주기적으로 제거 할 수 있습니다.
Adam Gent

7
ConcurrentHashMap의 Collections.synchronizedMap과보다 낫다 stackoverflow.com/questions/6692008/...
파블로 모레티

8
성능면에서 ConcurrentHashMap은 절대적으로 더 잘 수행되지만 가비지 수집기가 메모리를 회수 할 수 있도록 허용하는 것과 관련하여 WeakHashMap의 속성을 공유하지 않습니다. 이것은 귀하에게 중요하거나 중요하지 않을 수 있습니다.
Evan

4
그런 다음 ConcurrentHashMap<WeakReference<T>>. docs.oracle.com/javase/7/docs/api/java/lang/ref/…
jdmichal

19

메모리 내 자바 캐시의 또 다른 옵션은 cache2k 입니다. 인 메모리 성능은 EHCache 및 Google Guava 보다 우수 합니다 . cache2k 벤치 마크 페이지를 참조하세요 .

사용 패턴은 다른 캐시와 유사합니다. 다음은 예입니다.

Cache<String,String> cache = new Cache2kBuilder<String, String>() {}
  .expireAfterWrite(5, TimeUnit.MINUTES)    // expire/refresh after 5 minutes
  .resilienceDuration(30, TimeUnit.SECONDS) // cope with at most 30 seconds
                                          // outage before propagating 
                                          // exceptions
  .refreshAhead(true)                       // keep fresh when expiring
  .loader(new CacheLoader<String, String>() {
    @Override
    public String load(final String key) throws Exception {
      return ....;
    }
  })
  .build();
String val = cache.peek("something");
cache.put("something", "hello");
val = cache.get("something");

Google 구아바가 종속성으로있는 경우 구아바 캐시를 사용해 보는 것이 좋은 대안이 될 수 있습니다.


cruftex, 응용 프로그램을 닫으면 캐시가 등록 된 모든 데이터를 삭제합니까?
Menai Ala Eddine-Aladdin

10

imcache 를 쉽게 사용할 수 있습니다 . 샘플 코드는 다음과 같습니다.

void example(){
    Cache<Integer,Integer> cache = CacheBuilder.heapCache().
    cacheLoader(new CacheLoader<Integer, Integer>() {
        public Integer load(Integer key) {
            return null;
        }
    }).capacity(10000).build(); 
}

9

이 시도:

import java.util.*;

public class SimpleCacheManager {

    private static SimpleCacheManager instance;
    private static Object monitor = new Object();
    private Map<String, Object> cache = Collections.synchronizedMap(new HashMap<String, Object>());

    private SimpleCacheManager() {
    }

    public void put(String cacheKey, Object value) {
        cache.put(cacheKey, value);
    }

    public Object get(String cacheKey) {
        return cache.get(cacheKey);
    }

    public void clear(String cacheKey) {
        cache.put(cacheKey, null);
    }

    public void clear() {
        cache.clear();
    }

    public static SimpleCacheManager getInstance() {
        if (instance == null) {
            synchronized (monitor) {
                if (instance == null) {
                    instance = new SimpleCacheManager();
                }
            }
        }
        return instance;
    }

}

동기화 된 맵에 의존하는 문제는 이미 다른 답변에서 논의되었습니다.
sanity 2013 년

@sergeyB : 나는 ... 캐시를 구현하기위한 간단 유사한 솔루션에 대한 감사를 찾고 있었다
Prakruti Pathik

1
public static SimpleCacheManager getInstance() {해야한다 public synchronized static SimpleCacheManager getInstance() {, 그렇지 않으면 if (instance == null) {스레드로부터 안전하지 않습니다. 이 경우 모든 getInstance () 호출에 대해 동기화가 발생하므로 모니터 개체를 모두 제거 할 수 있습니다. 다음을 참조하십시오. javaworld.com/article/2073352/core-java/…
Can Kavaklıoğlu dec

싱글 톤에 열거 형을 사용하는 것이 좋습니까? dzone.com/articles/java-singletons-using-enum
Erk



0

Ehcache를 사용해 보 시겠습니까? 그것은 당신이 당신의 엿보기 기능을 제어 할 수 있도록 자신의 캐싱 만료 알고리즘을 연결할 수 있습니다.

디스크, 데이터베이스, 클러스터 등을 통해 직렬화 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.