[WLS, Java] Precompiled JSP Behavior on WebLogic 12c. Suddenly consuming more memory?

原文はこちら。
https://blogs.oracle.com/configandruntime/entry/precompiled_jsp_behavior_on_weblogic

最初のエントリとして、サーバーのメモリ消費量を最大限制御しつづける上でお役に立つかもしれないことを共有したいと思います。

weblogic.appcを使ってデプロイする前にコードをプリコンパイルし、アプリケーションの性能を向上させようとする場合、この問題に出くわす可能性があります。ご存知かもしれませんが、仮想プロセスのサイズはJavaヒープと非Javaヒープによって構成されています。このため、全てのオブジェクトとサーバー実行に必要なデータはJavaのヒープ外からのロードが多数発生します。この特定のケースでは、プリコンパイルされたJSPファイルをJavaヒープの外部に格納します。特にHotSpot JDKでは、PermSpaceに格納されてしまいます。

Well, why is this important?

WebLogic Server 11gから12cへアプリケーションを移行し、JSPをプリコンパイルする場合、アプリケーションを起動するたびにPermSpaceをどこからともなく消費することがわかります。この件の速やかな説明は明らかではありませんが、完全に予想されることなのです。

数多くのプリコンパイル済みJSPがアプリケーションで使われている場合、これは問題になるでしょう。

How can I know if I'm facing this problem?

クラスローディングのデバッグを有効(Javaのシステムプロパティ -verbose:class を使う)にすれば、アプリケーション起動時(つまり、例えば管理コンソールに入るか、WLSTを使用し、準備済み(Prepared)からアクティブ(Active)状態へ遷移するタイミング)にロードされる、全てのプリコンパイルされたJSPファイルを確認できます。
[Loaded javax.ws.rs.ext.Provider from file:/refresh/home/WLS/12.1.1/modules/com.sun.jersey.core_1.1.0.0_1-9.jar]
[Loaded $Proxy108 from sun.misc.Launcher$AppClassLoader]
[Loaded jsp_servlet.__dummyjsp1603 from file:/refresh/home/WLS/12.1.1/user_projects/domains/myDomain/servers/AdminServer/tmp/_WL_user/native_test_1211/7vonl8/war/WEB-INF/lib/_wl_cls_gen.jar]
[Loaded jsp_servlet.__dummyjsp1602 from file:/refresh/home/WLS/12.1.1/user_projects/domains/myDomain/servers/AdminServer/tmp/_WL_user/native_test_1211/7vonl8/war/WEB-INF/lib/_wl_cls_gen.jar]
[Loaded jsp_servlet.__dummyjsp1605 from file:/refresh/home/WLS/12.1.1/user_projects/domains/myDomain/servers/AdminServer/tmp/_WL_user/native_test_1211/7vonl8/war/WEB-INF/lib/_wl_cls_gen.jar]
[Loaded jsp_servlet.__dummyjsp1604 from file:/refresh/home/WLS/12.1.1/user_projects/domains/myDomain/servers/AdminServer/tmp/_WL_user/native_test_1211/7vonl8/war/WEB-INF/lib/_wl_cls_gen.jar]
[Loaded jsp_servlet.__dummyjsp1607 from file:/refresh/home/WLS/12.1.1/user_projects/domains/myDomain/servers/AdminServer/tmp/_WL_user/native_test_1211/7vonl8/war/WEB-INF/lib/_wl_cls_gen.jar]
...
...
...
[Loaded jsp_servlet.__dummyjsp1890 from file:/refresh/home/WLS/12.1.1/user_projects/domains/myDomain/servers/AdminServer/tmp/_WL_user/native_test_1211/7vonl8/war/WEB-INF/lib/_wl_cls_gen.jar]
メモリ使用量を控えめにしたい場合、アクセス権を基にこれらのプリコンパイルされたJSPだけをロードだけしたいのでしょうか。確かにそれが、ここでデフォルトの動作として起きていないことですからね。

Under the hood

WebLogic Server 12.1.1では、新しい機能が実装されています。これは、initContainerInitializer()と呼ばれるメソッドによって基本的に表されるものです。この問題でクラッシュしている場合には、アプリケーションを起動し、数個のスレッドダンプを収集すると、デプロイメントを利用可能にするために読み取り、膨らませる役目を担う次のメソッドがスレッド上に現れていることを確認できるでしょう。
[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=10 tid=0x0af82000 nid=0x1e9f runnable [0x353bd000]
java.lang.Thread.State: RUNNABLE
  at java.util.zip.ZipFile.read(Native Method)
  at java.util.zip.ZipFile.access$1200(ZipFile.java:31)
  at java.util.zip.ZipFile$ZipFileInputStream.read(ZipFile.java:460)
- locked (a java.util.jar.JarFile)
  at java.util.zip.ZipFile$1.fill(ZipFile.java:243)
  at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:141)
  at weblogic.utils.io.DataIO.readFully(DataIO.java:351)
  at weblogic.utils.io.DataIO.readFully(DataIO.java:328)
  at weblogic.utils.classloaders.ZipSource.getBytes(ZipSource.java:76)
  at weblogic.utils.classloaders.GenericClassLoader.defineClass(GenericClassLoader.java:321)
  at weblogic.utils.classloaders.GenericClassLoader.findLocalClass(GenericClassLoader.java:302)
- locked (a weblogic.utils.classloaders.GenericClassLoader)
  at weblogic.utils.classloaders.GenericClassLoader.findClass(GenericClassLoader.java:270)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:305)
- locked (a weblogic.utils.classloaders.GenericClassLoader)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:246)
  at weblogic.utils.classloaders.GenericClassLoader.loadClass(GenericClassLoader.java:179)
  at java.lang.Class.forName0(Native Method)
  at java.lang.Class.forName(Class.java:247)
  at weblogic.application.utils.annotation.ClassfinderClassInfos.loadClass(ClassfinderClassInfos.java:109)
  at weblogic.application.utils.annotation.ClassfinderClassInfos.getHandlesImpls(ClassfinderClassInfos.java:68)
  at weblogic.servlet.internal.War.getHandlesImpls(War.java:413)
at weblogic.servlet.internal.WebAppServletContext.initContainerInitializer(WebAppServletContext.java:1279)
at weblogic.servlet.internal.WebAppServletContext.initContainerInitializers(WebAppServletContext.java:1229)

  at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext.java:1726)
- locked (a weblogic.servlet.internal.WebAppServletContext)
  at weblogic.servlet.internal.WebAppServletContext.start(WebAppServletContext.java:2740)
  at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1704)
  at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:781)

赤で協調されている部分に気づきましたか?注意深く見ると、これらのメソッドは11gのコードにはないことがわかることでしょう。従って、WebLogic Server 11gで実行した場合、この挙動を見ることはないのです。おおっ、真ん前に決定的証拠がありますね。

Ok, problem is there... How do I fix it?

いい知らせがあります。この問題は既に対処済みということです。もし以前のWebLogic Server 11gの挙動に戻したい、ということであれば、2段階の方法を実施する必要があります。
  • パッチをインストール(WebLogic Server 12.1.1の場合のみ。12.1.2以上であればこの手順は無視してください)
    • 質問のバグは未発表の不具合です
      Bug 14805810 - psr:perf:soa severe impact on startup time,webappservletcontext.initcontainerini
  • デプロイメントディスクリプタ(weblogic.xml)を修正して、パッチが有効になるようにします

weblogic.xmlデプロイメント・ディスクリプタはパッチを有効にするためには以下のような感じになるはずです。
<?xml version="1.0" encoding="UTF-8"?>
<wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.4/weblogic-web-app.xsd">
  <wls:weblogic-version>12.1.1</wls:weblogic-version>
  <wls:context-root>native_test_1211</wls:context-root>
  <wls:container-descriptor>
    <wls:container-initializer-enabled>false</wls:container-initializer-enabled>
  </wls:container-descriptor>
</wls:weblogic-web-app>
デプロイメントプランを使うか、直接アプリケーションに指定するかのいずれかで設定できます。どちらでも効果があります。

パッチのインストール方法や、これを複製する方法に関する詳細は、以下のサポートドキュメントをご覧下さい。
WebLogic Server 12.1.1 Loads All Precompiled JSPs Into Native Memory Causing Out of Memory Problems (Doc ID 1571737.1)
https://support.oracle.com/rs?type=doc&id=1571737.1
まだ何かご質問や問題があれば、是非サポートに対してSR(Service Request)を起こしてください。必要な情報を回答できるかと思います。

0 件のコメント:

コメントを投稿