私たちのアプリケーションには、いくつか(実際には多く、約30)のWebサービスがあります。各Webサービスは独自のWARファイルに常駐し、アプリケーションの起動時に初期化される独自のSpringコンテキストを持っています。
また、Webサービスクラスに適用するアノテーション駆動型のアスペクトクラスもいくつかあります。最初のpoincut式は次のようになりました。
@Pointcut("execution(public * my.package.service.business.*BusinessServiceImpl.*(..))")
public void methodsToBeLogged() {
}
また、AOPは、構成への入力を通じてサービスで有効になりました。
しかし、Webサービスの数が増えるとOutOfMemoryException
、サーバーでsを経験し始めました。いくつかのプロファイリングと分析を行った後、AspectJExpressionPointcutクラスのインスタンスによって保持されているキャッシュによってメモリが使用されているように見えました。
各インスタンスのキャッシュは約5MBでした。また、3つの側面と30のサービスがあるため、合計で450MBのデータを保持する90のインスタンスが生成されました。
キャッシュの内容を調べたところ、my.package.service.businessパッケージの一部ではないクラスも含め、WARに存在するすべてのクラスのJavaリフレクションメソッドインスタンスが含まれていることがわかりました。ポイントカット式を変更して、追加のwithin
句を追加した後:
@Pointcut("execution(public * my.package.service.business.*BusinessServiceImpl.*(..)) &&
within(my.package.service.business..*)")
public void methodsToBeLogged() {
}
メモリ使用量は再び通常に低下しました。そして、すべてのAspectJExpressionPointcutインスタンスは、全体で1MB未満しかかかりませんでした。
誰かがそれがなぜであるか説明できますか?そして、なぜ最初のポイントカット式では不十分なのですか?のキャッシュがAspectJExpressionPointcut
共有されないのはなぜですか?