Fix memory leak on AOP Proxy class definition cache.
How to reproduce
- Like
@Validated
annotation with Request scope Controller like bellow
// Annnotation definition
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Controller
@Scope(WebApplicationContext.SCOPE_REQUEST)
@RequestMapping(method = { RequestMethod.GET, RequestMethod.HEAD })
@Transactional
@Validated
public @interface MyController {
}
@MyController
public class RootController {
@ModelAttribute("requireJs")
public boolean isRequireJs() {
return true;
}
@RequestMapping("/search")
public String search(
Model model,
@RequestParam(value = "space", required = false) @Max(value=100) String space) {
// ommit
}
}
- Aop class definition cache won't work well, therefore memory leak
Why
this bug is intruced by:
- https://github.com/spring-projects/spring-framework/pull/26017/files#diff-8b811560ae60c9f7937f0d378880f1b4366fa67ea7024db018931a26e3b449edL370-L376
-
https://github.com/spring-projects/spring-framework/pull/26017/files#diff-dd90aa36a7221a652e04631ac19dcb6693a9c841e43a90d36cc3caa51121630eL945-L947
-
Because
@Validated
annotation added,AbstractAdvisingBeanPostProcessor#postProcessAfterInitialization
add advice for@Validated
-
Before https://github.com/spring-projects/spring-framework/pull/26017/, cache in org.springframework.cglib.core.AbstractClassGenerator works well. Because org.springframework.aop.framework.AdvisedSupport#getConfigurationOnlyCopy copy org.springframework.aop.framework.AdvisedSupport#advisorsArray for create copy instance.
But after https://github.com/spring-projects/spring-framework/pull/26017/, use same reference of org.springframework.aop.framework.AdvisedSupport#advisors for create copy instance. and this advitors field update by AbstractAdvisingBeanPostProcessor#postProcessAfterInitialization
- When Create Aop class instance, try to reuse cache for class definition
Cache key is defined below code:
- org.springframework.cglib.proxy.Enhancer#createClass
- org.springframework.cglib.proxy.Enhancer#createHelper
org.springframework.cglib.proxy.Enhancer#filter is registered at https://github.com/spring-projects/spring-framework/blob/main/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java#L201-L202
- cache miss for class definition, memory leak happen
At AbstractAdvisingBeanPostProcessor#postProcessAfterInitialization, advice object
updated and therefore cache key is pollute, cache miss and memory leak happen.
So, When creating copy instance on org.springframework.aop.framework.AdvisedSupport#getConfigurationOnlyCopy, It is good that create new instance of ArrayList and copy all advices.
This bug reported by @hikoma Thanks!
Comment From: sbrannen
Thanks for the PR and the detailed report.
We'll look into it.
Comment From: sbrannen
Related issues:
-
26266
-
27395