2

此设置是否可以用作服务器端缓存?这些值会保留在内存中并且不会被 GC 处理吗?

Servlet 在应用服务器启动时创建,并且是应用程序中唯一的 Servlet。因此,如果 Servlet 停止,应用程序将关闭。该应用程序只能在一个 JVM 上运行。

public class HtmlServlet extends HttpServlet
{
   private ConcurrentHashMap<String, Object> cache;

   public void init() throws ServletException
   {
      cache = Cache.init();
   }

}

public class Cache
{

  private static ConcurrentHashMap<String, Object> cache;

  public synchronized static ConcurrentHashMap<String, Object> init()
  {
     if (cache == null)
     {
         cache = new ConcurrentHashMap<String, Object>();
     }
     return cache;
  }

  public static void set(String s, Object o) { ... }
  public static Object get(String s) { ... }
  public static void remove(String s) { .. }
}
4

7 回答 7

1

这看起来没有任何明显的缺陷。除了缓存可能会填满和崩溃的事实,因为没有什么可以自动删除旧条目。

如果您在使用缓存时不小心,您可能会引入一个微妙的内存泄漏,它可能会不断填满。

于 2013-09-25T12:11:52.167 回答
0

这会起作用,但它也会无限制地增长,而且它是侵入性的(你的所有代码都必须知道缓存;它没有实现Map)。使用 Guava 缓存可能是更实际的选择。

于 2013-09-25T12:12:10.200 回答
0

可能这不是您提出的问题的答案,但是您为什么不想使用EhCache之类的东西呢?它已经实现了缓存解决方案并且效果很好:)

编辑但回答你的问题 - 我认为你的解决方案也应该有效:)

于 2013-09-25T12:12:27.920 回答
0

您的方法将只被调用一次/JVM,因此您的方法中Servlet init不需要。您主要需要填充您的方法,在您的情况下,我认为即使不需要,因为您正在使用synchronizedCache initsynchronizecacheconcurrenthashmap

于 2013-09-25T12:16:37.957 回答
0

最简单的方法是使用Wea​​kHashMap。您还可以查看基于 SoftReferences的Guava CacheBuilder 。这两种类型的引用被 GC 收集的方式不同。SoftReferences 更适合缓存,但在 JSE 中没有内置实现。

于 2013-09-25T12:17:00.363 回答
0

您可以使用类似的东西,只需确保将所有值包装在WeakReferences. 你仍然会得到钥匙的增长。您可以扫描并清除键,get当您发现弱引用无效时清除键,或者WeakHashMap如果您不需要该ConcurrentHashMap功能,则使用 a。

于 2013-09-25T12:17:51.717 回答
0

您最好使用ServletContext上的属性,至少 Tomcat 的 ApplicationContext 使用 CHM。

于 2013-09-25T12:18:46.900 回答