Аспекты, сканирование слишком большого количества классов и кеш методов заполняет память

В нашем приложении есть несколько (на самом деле много, около 30) веб-сервисов. Каждая веб-служба находится в собственном WAR-файле и имеет собственный контекст Spring, который инициализируется при запуске приложения.

У нас также есть несколько классов аспектов на основе аннотаций, которые мы применяем к классам веб-сервисов. Вначале выражение «указатель» выглядело так:

@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. После изменения выражения сечения точки, чтобы дополнительно включить в предложение :

@Pointcut("execution(public * my.package.service.business.*BusinessServiceImpl.*(..)) && 
within(my.package.service.business..*)")
  public void methodsToBeLogged() {
  }

Использование памяти снова снизилось до нормального. И все экземпляры AspectJExpressionPointcut вместе занимали менее 1 МБ.

Может кто-нибудь объяснить, почему это так? И почему выражения среза первой точки недостаточно? Почему кэш AspectJExpressionPointcut не используется совместно?

6
задан Andrey Adamovich 5 November 2010 в 14:54
поделиться