Szukam prostej pamięci podręcznej Java w pamięci [zamknięta]


102

Szukam prostej pamięci podręcznej Java, która ma dobrą współbieżność (więc LinkedHashMap nie jest wystarczająco dobra) i którą można okresowo serializować na dysk.

Jedną z funkcji, której potrzebuję, ale która okazała się trudna do znalezienia, jest sposób „zerknięcia” na obiekt. Rozumiem przez to pobranie obiektu z pamięci podręcznej bez powodowania, że ​​pamięć podręczna przetrzymuje obiekt dłużej niż w innym przypadku.

Aktualizacja: Dodatkowym wymaganiem, o którym zapomniałem wspomnieć, jest to, że muszę mieć możliwość modyfikowania obiektów w pamięci podręcznej (zawierają tablice zmiennoprzecinkowe) w miejscu.

Czy ktoś może podać jakieś zalecenia?


1
Szukam czegoś podobnego, co jest „w trakcie” i jest lżejsze. Chcę go użyć do przechowywania niektórych danych we wtyczce Eclipse w stercie. Ehcache i JCS wydają się zbyt ciężkie / dystrybuowane / J2EE jak na mój gust.
Uri


Polecę Apache Ignite ( ignite.apache.org )
Bhagat S.,

1
To, że to pytanie jest zamknięte (6 lat po fakcie) i nadal jest czymś, nad czym ludzie się dziś zastanawiają, pokaż, jak zawodzi system moderatorów SO.
dustinevan

Odpowiedzi:


62

Ponieważ pierwotnie zadano to pytanie, biblioteka Google Guava zawiera teraz potężną i elastyczną pamięć podręczną. Poleciłbym używanie tego.


3
Pamiętaj, że Spring nie obsługuje już pamięci podręcznej guawy: stackoverflow.com/questions/44175085/ ...
sinner

@sanity czy implementuje Jcache?
Gaurav

Caffine jest również przyjemną i wydajną biblioteką do buforowania. Kofeina to wysokowydajna, prawie optymalna biblioteka buforująca oparta na Javie 8. Kofeina zapewnia pamięć podręczną w pamięci za pomocą interfejsu API inspirowanego Google Guava
Slavus

38

Ehcache jest całkiem dobrym rozwiązaniem na to i ma sposób na zerknięcie ( metodą jest getQuiet () ) w taki sposób, że nie aktualizuje znacznika czasu bezczynności. Wewnętrznie Ehcache jest zaimplementowany z zestawem map, podobnym do ConcurrentHashMap, więc ma podobne korzyści ze współbieżności.


2
Dzięki, dodatkowe pytanie: jeśli pobiorę obiekt z EHcache (powiedzmy tablicę) i zmodyfikuję go - czy obiekt zostanie zaktualizowany w pamięci podręcznej? to znaczy. czy EHCache utrzymuje odwołania do obiektów?
zdrowie psychiczne

1
Myślę, że tak, ale aby zrobić to bezpiecznie, musisz oczywiście odpowiednio zamknąć obiekt.
Alex Miller

Uwielbiam ehcache, ale jest to słoik o pojemności 10mb. Dużo za duży.
markthegrea

24

Jeśli potrzebujesz czegoś prostego, czy to pasuje do rachunku?

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

Nie zapisuje się na dysku, ale powiedziałeś, że chcesz prosty ...

Spinki do mankietów:

(Jak skomentował Adam, synchronizacja mapy ma duży wpływ na wydajność. Nie mówię, że pomysł nie ma włosów, ale wystarczyłby jako szybkie i brudne rozwiązanie.)


4
Synchronizacja całej gigantycznej mapy to ogromna kara. Możesz łatwo przechowywać słabe typy na współbieżnej mapie skrótów i usuwać je okresowo.
Adam Gent,

7
ConcurrentHashMap jest lepszy niż Collections.synchronizedMap stackoverflow.com/questions/6692008/ ...
Pablo Moretti

8
Pod względem wydajności ConcurrentHashMap działa zdecydowanie lepiej, ale nie ma wspólnych właściwości WeakHashMap w odniesieniu do zezwalania na odzyskanie pamięci przez moduł odśmiecania pamięci. To może być dla Ciebie ważne, ale nie musi.
Evan,

4
Następnie użyj ConcurrentHashMap<WeakReference<T>>. docs.oracle.com/javase/7/docs/api/java/lang/ref/…
jdmichal

19

Inną opcją dla pamięci podręcznej Java w pamięci jest cache2k . Wydajność w pamięci jest lepsza niż EHCache i Google Guava, zobacz stronę testów porównawczych cache2k .

Wzorzec użycia jest podobny do innych pamięci podręcznych. Oto przykład:

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");

Jeśli masz google guava jako zależność, wypróbowanie pamięci podręcznej guawy może być dobrą alternatywą.


cruftex, jeśli zamknę aplikację, pamięć podręczna zniszczy wszystkie zarejestrowane dane, czy nie?
Menai Ala Eddine - Aladdin

10

Możesz łatwo użyć imcache . Przykładowy kod znajduje się poniżej.

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

9

Spróbuj tego:

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;
    }

}

Problemy z poleganiem na zsynchronizowanej mapie zostały już omówione w innych odpowiedziach.
zdrowie psychiczne

@sergeyB: Szukałem podobnego rozwiązania, które jest proste do implementacji pamięci podręcznej ... Dzięki
Prakruti Pathik

1
public static SimpleCacheManager getInstance() {powinno być public synchronized static SimpleCacheManager getInstance() {inaczej if (instance == null) {nie jest bezpieczne dla wątków. W takim przypadku możesz usunąć cały obiekt monitora, ponieważ synchronizacja odbywa się dla wszystkich wywołań getInstance (), zobacz: javaworld.com/article/2073352/core-java/…
Can Kavaklıoğlu

Czy mogę polecić użycie wyliczenia dla singletona? dzone.com/articles/java-singletons-using-enum
Erk



0

Wypróbuj Ehcache ? Umożliwia podłączenie własnych algorytmów wygasania pamięci podręcznej, dzięki czemu można kontrolować funkcjonalność podglądu.

Możesz serializować na dysk, bazę danych, przez klaster itp ...

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.