java Spring Cache会导致内存泄漏问题吗?

fbcarpbf  于 2023-04-04  发布在  Java
关注(0)|答案(3)|浏览(284)

我正在尝试使用Spring Cache(@Cacheable annotation)在Sping Boot Application中的方法级别,但与其他Google guava缓存不同,我不知道Spring Cache是否会导致内存泄漏问题。因为它没有大小限制或刷新策略,数据将存储在应用程序中的位置和多长时间?我假设它是内存,但Spring本身会自动清除它吗?如果不会,当可能有数百万个请求进入应用程序时,会触发内存泄漏问题吗?
我的用例是每个请求都有一个繁重的方法,我希望在当前请求期间只执行该方法一次,请求完成后不需要将数据保留在Cache中,但我如何确保每次请求后都会清除Spring Cache?我知道有一个逐出操作,但是,如果我的请求在命中我的缓存逐出方法之前出错,那么它直接返回500,这意味着我的最后一个请求数据将始终位于该高速缓存内存中,越来越多的请求可能会导致内存泄漏,对吗?

2admgd59

2admgd591#

Spring框架的缓存支持和基础设施,无论是通过基于声明性注解的缓存还是Spring应用程序组件的划分来使用(使用Spring Annotations,例如@Cacheable,或使用JSR-107,JCache Annotations),或直接使用Spring的Cache API(不常见),只是一个“抽象”,因此Spring Cache Abstraction。默认情况下,NO底层缓存提供程序(此SPI的实现)。
当然,如果您使用Sping Boot (在核心Spring Framework之上或使用核心Spring Framework),并且您配置显式缓存提供程序(请参阅此处),例如Redis,则默认情况下,Spring Boot将配置并为Spring Boot应用程序提供ConcurrentHashMap缓存提供程序实现(请参阅此处)。
当文件规定:

  • 如果您的应用程序中不存在缓存库,则此为默认值。*

这意味着在Sping Boot 应用程序类路径上没有检测到缓存库,如Redis(例如使用 Spring Data Redis)。
然而,一般来说,选择一个底层的缓存提供者实现是一个很好的做法,比如Redis,或者在你的情况下,Google Guava,它可以在Spring的Cache Abstraction中定位为缓存提供者实现(例如,请参阅here)。
鉴于Spring框架的Cache Abstraction仅仅是一个 Facade,具有多个缓存提供程序实现所共有的缓存API/SPI,有效地为缓存功能提供了最低的公分母(例如put,get,evict,invalidate),那么对于你的问题,没有任何原因会导致Spring的“Cache”引起内存泄漏,从技术上讲,它是提供商实现的“缓存”,如Google Guave,Redis,Hazelcast,Apache Geode(VMW GemFire)等,如果首先在您的应用程序中存在泄漏,则实际上会导致内存泄漏。
换句话说,如果存在任何内存泄漏,那么它是由缓存提供程序引起的。
您应该参考缓存提供程序的文档来配置该高速缓存的关键方面,例如内存管理,这些方面明确声明超出Spring Framework的缓存抽象的控制范围。
这些方面超出核心Spring Framework控制的原因很简单,因为这些低级缓存功能(例如内存管理)的配置通常是非常特定于提供程序的,并且从一个提供程序到下一个提供程序变化很大,特别是在功能和功能方面。
我希望这个解释能让您清楚Spring提供该高速缓存抽象的位置及其职责。
通过坚持抽象,如果您的应用程序需求、UC或SLA发生变化,它可以有效地简化缓存提供程序之间的切换。

3pvhb19x

3pvhb19x2#

你仍然可以指定你想要的缓存。
“...使用受Google Guava启发的API提供内存缓存”
您仍然可以将其配置为maximumSize

spring:
    cache:
        cache-names: instruments, directory
        caffeine:
            spec: maximumSize=500, expireAfterAccess=30s

要启用它,您只需添加依赖项并在config类中添加@EnableCaching(当然,还要在方法中添加@Cacheable
参见:

ioekq8ef

ioekq8ef3#

在Spring应用程序中,也许你可以通过以下方式禁用该高速缓存:

spring.cache.type=NONE

默认情况下,缓存类型会自动检测和配置。但是,您可以通过将spring.cache.type添加到配置中来指定要使用的缓存类型。要禁用它,请将值设置为NONE。
当您想为特定配置文件执行此操作时,请将其添加到该配置文件application.properties在本例中,请修改application-dev.properties并添加

spring.cache.type=NONE

这将禁用缓存。

相关问题