В нашем приложении у нас есть несколько (всего около 30) веб-сервисов.Каждый веб-сервис находится в своем собственном файле WAR и имеет собственный контекст Spring, который инициализируется при запуске приложения.
У нас также есть ряд классов аспектов, управляемых аннотациями, которые мы применяем к классам веб-сервисов.Вначале выражение poincut выглядело так:
@Pointcut("execution(public * my.package.service.business.*BusinessServiceImpl.*(..))")
public void methodsToBeLogged() {
}
И AOP был включен для сервисов посредством входа в конфигурацию.
Но когда число веб-сервисов выросло, мы начали испытывать OutOfMemoryException
с на наших серверах.После некоторого профилирования и анализа оказалось, что память занята кешем, который хранится экземплярами класса AspectJExpressionPointcut.
Кэш каждого экземпляра занимал около 5 МБ.И так как у нас было 3 аспекта и 30 сервисов, это привело к тому, что 90 экземпляров содержали 450 МБ данных.
Изучив содержимое кэша, мы поняли, что он содержит экземпляры метода отражения Java для всех классов, существующих в WARдаже те, которые не являются частью пакета my.package.service.business.После изменения выражения среза точки дополнительно добавьте within
предложение:
@Pointcut("execution(public * my.package.service.business.*BusinessServiceImpl.*(..)) &&
within(my.package.service.business..*)")
public void methodsToBeLogged() {
}
Использование памяти снова нормализовалось.И все экземпляры AspectJExpressionPointcut заняли менее 1 МБ вместе.
Может кто-нибудь объяснить, почему это так?И почему первой точки среза выражения недостаточно?Почему кеш AspectJExpressionPointcut
не является общим?