1

現在、Windows XP Embedded スタート メニューの starup フォルダーに配置された .bat ファイルによって開始された jar によって実行される 4 つの異なる Java アプリがあります。Firefoxも起動します。ここで、Firefox または Java アプリのいずれかがシャットダウンします。メモリが不足していると思います(512 MB RAMのWin XP Embedded)。

4 つの Java アプリは、

  • HMI バックエンド (Spark「マイクロ」フレームワークで構築)
  • PLC から H2 データベースにデータを記録するロガー アプリ。これは Timer/Timertask を使用して
  • h2 データベース サーバー
  • 定期的なジョブを実行するスケジューラ。これはQuartzを使用することによって。

したがって、これらの Java アプリはそれぞれ独自の JVM で開始されます (私の知る限り)。最初の質問は、これら 4 つのアプリを 4 つではなく 1 つの JVM で実行することによって、これら 4 つのアプリのメモリ使用量を削減できないかということです。もしそうなら、これらの各アプリを起動するために使用するスレッドはありますか?

それ以外に、メモリ フットプリントを下げるために最初にすべき基本的なことは何ですか。私は「実際の」Java プログラミングにはまったく慣れていません。H2 接続プール、オブジェクトの再利用、他には? JconsoleとそのXmxのもの?

おそらく素朴ですが、GCが「すべて」を処理してくれると本当に思っていました。ないと思います?=)

編集: HMI バックエンドは Jetty Web サーバーを使用します。また、すべてのコードはオープン ソースまたは私が作成したものです。

編集 2: Web フレームワーク: http://www.sparkjava.com/。Jetty (jetty-webapp-7.3) ではなく、フレームワークを介して静的メディアを提供しています。これは、メモリ使用量を改善するために検討するものでしょうか? HMI Web アプリのその他のコンポーネントは、freemarker テンプレート エンジン、gson、servlet-api-3、slf4j、および log4j です。

おそらく、webapp の開始時にロガーとスケジューラーをスレッドで開始しようとする可能性があります。次に、2 つの JVM を実行するだけです。1 つは webapp 用、もう 1 つはデータベース サーバー用です。

Java 7 を使用していますが、これは 32 ビット システムです。うまくいけば、本番用になります(または私は困っています)。

4

2 に答える 2

4

一連の個別のプロセスから単一のプロセスに移行することは、通常、単に「スイッチを切り替える」だけではありません。これらは根本的に異なるアーキテクチャです。

  • 同じプロセスに属するスレッドは、互いに「見る」ことができる特定のリソース (メモリ空間、ファイルハンドルなど) を共有します。非常に「軽量」な方法で相互に通信し、データを共有できます。
  • 異なるプロセスは、ある程度「分離された」ユニットです。お互いのメモリやファイルハンドルなどを単に「のぞき見」することはできず、「より重い」方法で相互に通信する必要があります (たとえば、ソケットやプロセスによって提供されるその他の機能を介して)。 OS)。

さて、あるモデルから別のモデルにどれだけ簡単に移行できるか、またどれだけの費用がかかるかは、特定のコンポーネントが何を行っているか、およびそれらがどのように相互作用するかによって異なります. あなたが言及したコンポーネントのいくつかに精通していませんが、あなたの説明から、本質的に相互接続された「ブラックボックス」の山があり、多くの再構築を行うことができないように聞こえます.

したがって、さまざまなコンポーネントのドキュメントを参照し、起動時に VM サイズ (または「ヒープ サイズ」) を指定できるかどうかを確認してから、コンポーネントを必要最小限に抑えてみることをお勧めします。(おそらく、あなたのロガープロセスは何百メガバイトも必要としません...)

原則として、Windows は「メモリ不足のためにプロセスをシャットダウン」すべきではありません。JVM のヒープのビットを仮想メモリの内外でスワップする必要がある場合、地獄のように激しく動き始める可能性があります[*]。ただし、実際にプロセスをシャットダウンするべきではありません。一方、特定の Java アプリは、ヒープからメモリを割り当てようとしているときに OutOfMemoryError を受け取ると、シャットダウンする (または、例外処理に応じてデフォルトの動作としてシャットダウンする) ことを決定する場合があります。さまざまなコンポーネントのログは、何が起こったことを示唆していますか?

[*] ネイティブ アプリケーションとは異なり、Java アプリケーションは仮想メモリにうまく対応できません。Java にとって、そのメモリは単一の「ヒープ」であり、常にページ インされることを効果的に期待しているからです。JVM に合計ヒープ サイズを割り当てないようにする必要があります。これは、マシンの物理メモリの量に近いか、またはそれを超えています。

于 2012-06-12T19:31:45.570 に答える
1

Neil Coffeyの回答ですでにカバーされている側面については、意図的に触れません。

したがって、これらの Java アプリはそれぞれ独自の JVM で開始されます (私の知る限り)。最初の質問は、これら 4 つのアプリを 4 つではなく 1 つの JVM で実行することによって、これら 4 つのアプリのメモリ使用量を削減できないかということです。もしそうなら、これらの各アプリを起動するために使用するスレッドはありますか?

いいえ、または簡単ではありません (Neil Coffey の回答を参照)。

java.exeただし、コマンドライン引数をプログラムに渡すことで、これらの .bat ごとに Java メモリ設定を微調整できます。

メモリ設定がかなり制限されていることを考慮し、少なくとも Java SE 6 Update 10 を使用していると仮定すると、G1 ガベージ コレクタを試すことをお勧めします。G1 ガベージ コレクタを使用すると、比較的低いメモリ設定で適切なパフォーマンスを得ることができます。

たぶん、このようなものを渡して、必要に応じて調整してみてください:

-Xss64k -Xms128m -Xmx128m -XX:PermSize=64m -XX:MaxPermSize=64m -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:+UseCompressedStrings -XX:+UseCompressedOops

XX:+UseCompressedOopsは x64 JVM 専用でありXX:+UseCompressedStrings、JVM のバージョンによっては (および - も) 機能しない場合があることに注意してください。また、それが生産用なのか個人用なのかはわかりません。本番環境で使用する場合は、これら 2 つをそのままにして、 -XX:+UseG1GC` までのものを使用することをお勧めします。

上記は、1 台のマシンで Eclipse の複数のインスタンスを実行する必要があり、2 GB の RAM でかなり大きなプロジェクトを構築する必要がある場合に使用する設定のバリエーションです。残念ながら、あなたの環境はもう少しハードコアですが、一度にこのアプリを 1 つずつ試して、どれだけ絞って適応できるかを確認してください。

可能であれば、プロセスが何を行っているかについてより多くの情報を提供してください。そうすれば、必要なメモリ量を評価できるようになります。場合によっては、スタック サイズとヒープ サイズをさらに減らすことができます。私たちが知れば知るほど、設定を微調整するときに暗闇でタップすることが少なくなります.

それ以外に、メモリ フットプリントを下げるために最初にすべき基本的なことは何ですか。私は「実際の」Java プログラミングにはまったく慣れていません。H2 接続プール、オブジェクトの再利用、他には? JconsoleとそのXmxのもの?

H2 はすでにかなり軽量で、良い選択のように思えます。

JConsole は役に立ちませんが、JVisualVM を試してみるのもよいでしょう。プロファイリングに少しは役立ちます。または、余裕があれば JProfiler を目指してください。それ以外の場合、Eclipse には優れたメモリ アナライザーがあります。

おそらく素朴ですが、GCが「すべて」を処理してくれると本当に思っていました。ないと思います?=)

これは魔法ではなく、未使用のオブジェクトを再利用するだけです。それらへの参照がある場合、それらが必要かどうかはわかりません。そのため、参照を存続させないようにするか (通常は、コレクションまたは相互リンクされた複合オブジェクトを保持することによって)、または長期参照が必要な場合は、弱い参照またはソフト参照 (またはキャッシュの実装) を確認してください。

編集: HMI バックエンドは Jetty Web サーバーを使用します。また、すべてのコードはオープン ソースまたは私が作成したものです。

詳細を教えてください。さらに掘り下げることができます。


他にできることは、代替の JVM を調べることです。明らかに環境がかなり制限されている組み込みシステム用のものがいくつかあります。


スケジューリング ジョブの複雑さによっては、Quartz に依存せずに独自のスケジューラを展開できます。特に重いというわけではありませんが、すべての MB を圧縮する必要がある場合は、それがリストの最初に取り除こうとする要素になります。

于 2012-06-12T23:52:47.020 に答える