Buscando caché en memoria de Java simple [cerrado]


102

Estoy buscando un caché en memoria de Java simple que tenga buena concurrencia (por lo que LinkedHashMap no es lo suficientemente bueno) y que se pueda serializar en el disco periódicamente.

Una característica que necesito, pero que ha resultado difícil de encontrar, es una forma de "mirar" un objeto. Con esto me refiero a recuperar un objeto de la caché sin hacer que la caché se aferre al objeto más tiempo del que tendría de otra manera.

Actualización: un requisito adicional que olvidé mencionar es que necesito poder modificar los objetos en caché (contienen matrices flotantes) en su lugar.

¿Alguien puede dar alguna recomendación?


1
Estoy buscando algo similar que esté "dentro del proceso" y sea más ligero. Quiero usarlo para almacenar algunos datos dentro de un complemento de Eclipse en el montón. Ehcache y JCS parecen demasiado pesados ​​/ distribuidos / J2EE para mi gusto.
Uri


Recomendaré Apache Ignite ( ignite.apache.org )
Bhagat S.

1
Que esta pregunta esté cerrada (6 años después del hecho) y que todavía es algo que la gente se pregunta hoy, muestra cómo está fallando el sistema de moderadores de SO.
dustinevan

Respuestas:


61

Dado que esta pregunta se hizo originalmente, la biblioteca Guava de Google ahora incluye un caché potente y flexible. Recomendaría usar esto.


3
Tenga en cuenta que Spring ya no admite la caché de Guava: stackoverflow.com/questions/44175085/…
sinner

@sanity ¿implementa Jcache?
gaurav

Caffine también es una biblioteca de almacenamiento en caché agradable y eficaz . La cafeína es una biblioteca de almacenamiento en caché casi óptima de alto rendimiento basada en Java 8. La cafeína proporciona una caché en la memoria utilizando una API inspirada en Google Guava
Slavus

37

Ehcache es una solución bastante buena para esto y tiene una forma de echar un vistazo ( getQuiet () es el método) de manera que no actualiza la marca de tiempo inactiva. Internamente, Ehcache se implementa con un conjunto de mapas, algo así como ConcurrentHashMap, por lo que tiene tipos similares de beneficios de concurrencia.


2
Gracias, una pregunta adicional: si recupero un objeto de EHcache (digamos, una matriz) y lo modifico, ¿el objeto se actualizará en la caché? es decir. ¿EHCache mantiene referencias a los objetos?
cordura

1
Creo que sí, pero para hacer esto de forma segura, por supuesto, debe bloquear adecuadamente el objeto.
Alex Miller

Me encanta ehcache, sin embargo, es un frasco de 10 MB. Demasiado grande.
markthegrea

23

Si necesita algo simple, ¿esto se ajusta a la factura?

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

No se guardará en el disco, pero dijiste que querías simple ...

Enlaces:

(Como comentó Adam, sincronizar un mapa tiene un impacto en el rendimiento. No digo que la idea no tenga pelos en ella, pero sería suficiente como una solución rápida y sucia).


4
Sincronizar todo un mapa gigantesco es una gran penalización. Puede almacenar fácilmente tipos débiles en un mapa hash concurrente y eliminarlos periódicamente.
Adam Gent

7
ConcurrentHashMap es mejor que Collections.synchronizedMap stackoverflow.com/questions/6692008/…
Pablo Moretti

8
En cuanto al rendimiento, ConcurrentHashMap tiene un rendimiento absolutamente mejor, pero no comparte las propiedades de un WeakHashMap con respecto a permitir que el recolector de basura reclame memoria. Esto puede ser importante para usted o no.
Evan

4
Entonces usa ConcurrentHashMap<WeakReference<T>>. docs.oracle.com/javase/7/docs/api/java/lang/ref/…
jdmichal

19

Otra opción para un caché de Java en memoria es cache2k . El rendimiento en memoria es superior al de EHCache y google guava, consulte la página de pruebas de rendimiento de cache2k .

El patrón de uso es similar a otros cachés. Aquí hay un ejemplo:

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

Si tiene google guava como dependencia, probar el caché de guayaba puede ser una buena alternativa.


cruftex, si cierro mi aplicación la caché destruirá todos los datos registrados o no?
Menai Ala Eddine - Aladdin

10

Puedes usar imcache fácilmente . A continuación se muestra un código de muestra.

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

9

Prueba esto:

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

}

Los problemas de confiar en un mapa sincronizado ya se discutieron en otras respuestas.
cordura

@sergeyB: Estaba buscando una solución similar que sea simple para implementar el caché ... Gracias
Prakruti Pathik

1
public static SimpleCacheManager getInstance() {debería ser de public synchronized static SimpleCacheManager getInstance() {otra manera if (instance == null) {no es seguro para subprocesos. En cuyo caso, puede eliminar el objeto del monitor todos juntos, ya que la sincronización tiene lugar para todas las llamadas getInstance (), consulte: javaworld.com/article/2073352/core-java/…
Can Kavaklıoğlu

¿Puedo recomendar usar una enumeración para singleton? dzone.com/articles/java-singletons-using-enum
Erk



0

¿Prueba Ehcache ? Le permite conectar sus propios algoritmos de caducidad de almacenamiento en caché para que pueda controlar su funcionalidad de inspección.

Puede serializar en disco, base de datos, en un clúster, etc.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.