我使用hashmap作为缓存来存储id和name。因为它经常被使用,并且贯穿应用程序的整个生命周期。对于使用该应用程序的每个用户,hashmap中存储了大约5000个或更多(取决于工作区)id和名称。在某个时候,会抛出java.lang.outofmemoryerror异常。因为我在hashmap中保存了很多(id,name)。
我不想清除hashmap缓存值。但我知道为了提高效率,我们必须使用lru方法或其他方法清除缓存。
注意:我不想使用redis、memcached或任何内存键值存储。
用例:slack将在每条消息中返回id而不是用户名。
例如:hello@john doe=return hello@dxap123。
我不希望每一条消息都通过api来获取用户名。
如果我的方法有问题,有人能给我提供一个有效的替代方法或者纠正我吗。?
3条答案
按热度按时间vdgimpew1#
对于5000个键值对,它不应该通过
OutOfMemoryException
. 如果它抛出相同的值,则说明您没有正确管理hashmap。如果您有超过5000个条目,并且想要hashmap的替代项,那么可以使用ehcache
,这是一种广泛采用的java缓存,具有分层存储选项,而不是内存缓存技术。ehcache支持的内存区域包括:
堆上存储:使用java堆内存来存储缓存项,并与应用程序共享内存。垃圾回收也会扫描缓存。这种记忆很快,但也很有限。
堆外存储:使用ram存储缓存项。此内存不接受垃圾回收。内存仍然相当快,但比堆上内存慢,因为缓存项必须先移动到堆上内存才能使用。
磁盘存储:使用硬盘存储缓存项。比ram慢得多。建议使用仅用于缓存的专用ssd。
你可以在这里找到文件。http://www.ehcache.org/documentation/
如果您正在使用
spring-boot
您可以按照本文实现相同的功能。https://springframework.guru/using-ehcache-3-in-spring-boot/
ffx8fchx2#
如果“名称”不是唯一的,那么在将“名称”插入Map之前尝试调用string.intern(),这样可以减少内存使用。
oxosxuxt3#
就像其他人说的5000不应该给你内存不足,但如果你不保持Map大小的限制,最终你会得到内存不足的错误。应该缓存最近使用或最常用于优化Map大小的值。
GoogleGuava库有缓存实现,我认为它适合您的用例
https://github.com/google/guava/wiki/cachesexplained