在我们的应用程序中,我们有几个(实际上很多,大约 30 个)Web 服务。每个 Web 服务都驻留在自己的 WAR 文件中,并有自己的 Spring 上下文,该上下文在应用程序启动时被初始化。
我们还有许多注释驱动的方面类,我们将它们应用于 Web 服务类。一开始,切入点表达式看起来像这样:
@Pointcut("execution(public * my.package.service.business.*BusinessServiceImpl.*(..))")
public void methodsToBeLogged() {
}
并且通过配置条目在服务上启用了 AOP。
但是当网络服务的数量增加时,我们开始OutOfMemoryException
在我们的服务器上体验 s。在进行了一些分析和分析之后,似乎内存被 AspectJExpressionPointcut 类的实例保存的缓存占用。
每个实例的缓存大约为 5 MB。由于我们有 3 个方面和 30 个服务,因此总共有 90 个实例持有 450MB 的数据。
在检查缓存的内容后,我们意识到它包含 WAR 中存在的所有类的 Java 反射方法实例,即使是那些不属于 my.package.service.business 包的类。将切入点表达式修改为具有附加within
子句后:
@Pointcut("execution(public * my.package.service.business.*BusinessServiceImpl.*(..)) &&
within(my.package.service.business..*)")
public void methodsToBeLogged() {
}
内存使用再次下降到正常水平。并且所有 AspectJExpressionPointcut 实例总共占用不到 1MB。
有人可以解释这是为什么吗?为什么第一个切入点表达式还不够?AspectJExpressionPointcut
为什么不共享缓存?