问题描述
我正在使用哈希图作为缓存来存储ID和名称。因为它经常使用,并且在应用程序的整个生命周期中都有效。 对于使用该应用程序的每个用户,约有5000个以上(取决于工作空间)的ID和名称存储在哈希图中。有时会抛出 java.lang.OutOfMemoryError 异常。因为我在哈希图中保存了很多(id,name)。
我不想清除哈希映射缓存值。但是我知道要有效,我们必须使用LRU方法或其他方法清除缓存。
注意:我不想使用Redis,Memcached或任何内存中键值存储。
用例:松弛将返回id代替每个用户名 消息。
例如:Hello @john doe =返回Hello @ dxap123。
如果我的方法做错了什么,有人可以为我提供替代的有效方法还是对我进行纠正??
解决方法
就像其他人说的那样,不应该让5000占用内存,但是如果您不限制地图的大小,那么最终将出现内存不足错误。您应该缓存最近使用或最常用的值以优化地图的大小。
Google番石榴库具有我认为适合您用例的缓存实现
https://github.com/google/guava/wiki/CachesExplained
,对于5000个键值对,不应通过OutOfMemoryException
。如果它抛出相同的消息,则说明您没有正确管理HashMap。如果您有5000多个项目,并且想要替代哈希表,则可以使用ehcache
,这是一种广泛采用的Java缓存,具有分层存储选项,而不是使用内存中缓存技术。
Ehcache支持的内存区域包括:
堆上存储:使用Java堆内存来存储缓存条目并与应用程序共享内存。高速缓存也由垃圾收集扫描。该内存非常快,但也非常有限。
堆外存储:使用RAM存储缓存条目。此内存不受垃圾回收的限制。仍然是相当快的内存,但是比堆上内存要慢,因为缓存条目必须先移到堆上内存才能使用。
磁盘存储:使用硬盘存储高速缓存条目。比RAM慢得多。建议使用专用于缓存的专用SSD。
您可以在此处找到文档。 http://www.ehcache.org/documentation/
如果您使用的是spring-boot
,则可以按照本文实施。
https://springframework.guru/using-ehcache-3-in-spring-boot/
,如果“名称”不是唯一的,则在将“名称”插入到映射之前尝试调用String.intern(),这样可以减少内存使用。