2

我想在内存中缓存对象。要求如下:

  1. 每个记录/对象都与一个唯一键相关联。
  2. 要存储 400-500 条记录/对象。如果记录数增加超过指定限制,则应逐出较旧的记录。
  3. 记录的存储时间不应超过 2 分钟。
  4. 当 JVM 内存不足时(一种弱引用)应该缩小。
  5. 不能使用第三方库,因为它是一个小模块,目的只是减少不必要的网络访问。
  6. 写入更多,读取更少

这里的安全性也是一个问题,因为我们要缓存一些敏感数据。这些数据将被缓存在内存中。我真的应该担心安全性并加密数据吗?

我正在寻找一个提供类似功能的 Java 类。

目前我正在考虑扩展WeakHashMap和实施各种私有/公共方法以符合要求。

如果您有任何其他想法,请在这里分享。

4

3 回答 3

3

你不想使用WeakHashMap. SoftHashMap会更接近,但在标准库中不可用。如果我是你,我会查看Guava 的缓存类以获取提示。

但这里有一些额外的想法:

当 JVM 内存不足时(一种弱引用)应该缩小。

你的意思是soft reference。但无论如何,这个要求对我来说有点味道。我承认这可能是一个有效的要求,但你很少真正需要这个。如果您的记录的大小可以合理地预测,并且如果您计划对要缓存的记录数量进行硬性限制,那么您可能不需要这种复杂性。

不应使用第三方库。

每个人都提到了这一点,他们是对的。

在安全方面,加密缓存在内存中的数据的有效性是值得怀疑的。您还必须将加密密钥保存在内存中。我敢打赌,除了攻击者阅读你的记忆内容之外,还有很多事情需要担心。

于 2012-09-18T17:55:35.670 回答
2

不,你不应该这样做。WeakHashMap 不是缓存!

现在很容易理解为什么 WeakHashMap 不能用于缓存。首先它无论如何都不起作用,因为它对键使用软引用而不是映射值。但除此之外,垃圾收集器会积极回收仅由弱引用引用的内存。这意味着一旦您丢失了对作为 WeakHashMap 中的键工作的对象的最后一个强引用,垃圾收集器将很快回收该映射条目。

...

那么我到底如何在 Java 中实现缓存呢?

我的建议是使用免费提供的 Cache 实现之一,JCSOSCache等。这些库通过 LRU 和 FIFO 策略提供更好的内存管理,例如磁盘溢出、数据过期和许多其他可选的高级功能。

正如@user463324 所提到的,您应该只使用已经实现此功能的库,例如Google Guava,它在Apache 2.0许可下,没有理智的企业会遇到问题。此处未发明并不是忽略解决方案的好理由。

于 2012-09-18T17:41:12.207 回答
0

您有两个选择:JCS 或 Memcache/EHCache

这两个选项在功能上是等效的,但有一些关键的区别。当您使用 JCS 时,缓存的对象不会被序列化/反序列化。它们保留为 java 对象,因此存储和检索它们非常快。但是,这意味着您的缓存位于 JVM 内部,因此使用 JVM 的堆,并且其他 JVM 也无法访问。[JCS 提供某种类型的分布式功能作为插件]。

另一方面,Memcache/Ehcache 是在执行 put/get 操作时执行序列化/反序列化的外部缓存。在某些极端情况下,这可能会抵消缓存的好处。因此,速度基准测试是必不可少的。如果合适,它是分布式的,它使用自己的内存,可以在另一个盒子上。但这也意味着,您必须考虑 JVM 和外部缓存之间的数据安全性。

于 2012-09-18T17:52:48.713 回答