6

Webサーバー上でWebアプリごとに1つずつ、複数のJavaプロセスを実行したいと思います。サポートするクラスとjarファイルがたくさんあるWebフレームワーク(Play)を使用していますが、Javaプロセスは大量のメモリを使用します。1つのPlayプロセスでは、約225MBの「常駐プライベート」メモリが表示されます。(これは、Java1.7.0_05を使用するMacOS Xでテストしています。)アプリ固有のコードは、わずか数MBである可能性があります。典型的なJavaWebアプリは1つのサーバープロセス(Tomcatなど)に追加されたjarであることがわかっていますが、Playを実行する標準的な方法はスタンドアロンのアプリ/プロセスであるようです。これらがCプログラムの場合、その200MBのほとんどは共有ライブラリであり、各アプリで複製されません。これをJavaで実現する方法はありますか?クラスデータ共有に関するページがいくつかありますが、それはコアランタイムクラスにのみ適用されるようです。

4

4 に答える 4

5

現時点では、Oracle VMでは、これは不可能です。

しかし、私は同意します。特に、Javaにはそれを自動的に行うために必要なすべての情報があるので、これは素晴らしい機能になるでしょう。

何よりも、これが機能しない唯一の理由はJITだと思います。JITは実行時の動作を考慮に入れています。したがって、アプリAがアプリBとは異なるパターンでコードを使用すると、実行時に異なるアセンブラーコードが生成されます。

しかし、通常の「パターン」は「このコードが使用される頻度」です。したがって、アプリAが何らかのメソッドを頻繁に呼び出し、Bが呼び出さなかった場合でも、Aはコードの最適化/コンパイルの代金をすでに支払っているため、コードを共有できます。

試すことができるのは、複数のアプリケーションをWARファイルとして単一のVMにデプロイすることです。しかし、私の経験からすると、スレッドローカルまたはシャットダウンフックを正しくクリーンアップしないコードで問題が発生することがよくあります。

于 2012-11-21T15:33:28.600 に答える
4

IBM JDKには、これを実現するためのjvmパラメーターがあります。@http://www.ibm.com/developerworks/library/j-sharedclasses/をチェックしてください

そして、これは次のステップに進みます:http ://www.ibm.com/developerworks/library/j-multitenant-java/index.html

于 2013-12-04T00:04:42.437 に答える
1

仮想ホストをサポートするサーブレットコンテナを使用している場合(Tomcatがサポートしていると思います)、play2-war-pluginを使用できます。Play 2.1から、常にルートアプリであるという要件が解除されるため、おそらく任意のサーブレットコンテナを使用できるようになります。

すべてのクラスが再度読み込まれないように、warファイルを微調整WEB-INF/libしてサーブレットコンテナのlibディレクトリに移動する必要があり、シングルトンまたは他の形式のクラス共有を使用している場合、アプリに影響を与える可能性があることに注意してください。データ。

于 2012-11-21T15:31:42.720 に答える
1

JVMインスタンス間でメモリを共有する問題は、モバイルプラットフォームでより差し迫っています。私が知る限り、AndroidにはZygoteでの解決策があります。つまり、VMが初期化され、アプリを実行するとfork()編集されます。LinuxはRAMページでコピーオンライトを使用するため、ほとんどのデータが複製されることはありません。

Linuxで実行していて、VMとしてDalvikを使用してみたい場合は、このソリューションの移植が可能かもしれません(DalvikにTomcatの移植が機能しているという主張を見ました)。これは膨大な量の作業であり、最終的にはメモリのアップグレードにかかる費用を数ドル節約できると思います。

于 2012-11-21T15:40:42.377 に答える