0

ユーザーがXMLファイルを投稿するサーブレットがあります。

私はそのファイルを次のように読みました:

String xml = request.getParameter("...");

ここで、xmlドキュメントが10KBであるとしましょう。変数を作成したので、その変数xmlに10KBのメモリを使用しています。

次に、そのxmlを(xercesを使用して)解析する必要があり、saxparsers parseメソッド(http://docs.oracle.com/javase/1.5.0/docs/api/)に渡すときに入力ストリームに変換しました。 javax / xml / parser / SAXParser.html)。

したがって、文字列をストリームに変換すると、メモリ使用量が2倍になりますか?

これについていくつかの説明が必要です。

コードをステップ実行しているときにプロセスをvisualvmまたはjconsoleに接続すると、デバッガーでコードをステップ実行するときに追加のメモリを使用しているかどうかを確認できますか?

このエンドポイントは大きな打撃を受けるため、これを非効率的に行っていないことを確認したいと思います。

4

5 に答える 5

1

10,000バイトのテキストは通常​​20KBになります。

テキストを処理する場合、データ構造の作成など、その情報を使用して何かを行うため、通常は2〜10倍のメモリが必要です。

これは、200KBが必要になる可能性があることを意味します。ただし、PCではこれが1セントの価値があることを考えると、通常は心配する必要はありません。リソースが大幅に制限されているデバイスを使用している場合は、処理をサーバーなどの別のデバイスに移動することを検討します。

于 2012-05-16T19:59:09.000 に答える
1

実際に実行する前に、コードを最適化している可能性があると思います。JVM は非常に優れており、未使用のメモリをすばやく回復できます。

しかし、あなたの質問に答えてString xml = request.getParameter("...");もメモリが2倍になるわけではなく、ポインタに4バイトまたは8バイト(JVMが圧縮ポインタを使用しているかどうかによって異なります)が割り当てられるだけです。

xml の解析は異なります。SAX パーサーはメモリ効率が非常に高いため、メモリをあまり使用しません。Handler ごとに約 20 バイトと、使用しているインスタンス変数を加えたものだと思います...そして明らかに、生成する可能性のある余分なオブジェクトハンドラー。

したがって、あなたが持っているコードは、可能な限りメモリ効率が良いように見えます (もちろん、ハンドラーにあるものによって異なります)。

そのコードをデバイスに埋め込んだり、1 秒間に 10 万回実行したりしない限り、最適化する必要があることが確実でない限り、何も最適化しないことをお勧めします。JVM には、コードを最適化するための非常に高度なロジックがあり、ガベージ コレクターは、存続期間の短いオブジェクトを非常に高速に回復します。

于 2012-05-16T20:01:29.833 に答える
1

ユーザーが大量のファイルをサーブレットに戻すことができる場合は、getParameter() メソッドを使用せず、ストリームを直接処理することをお勧めします - Apache File Upload Library

そうすれば、InputStream で SAX パーサーを使用できます (また、処理前にテキスト全体をメモリにロードする必要はありません) - String ベースのソリューションで行う必要があるように。

このアプローチはスケーラビリティに優れており、String xml = getParameter(...) ソリューションと比較して、要求ごとに必要なメモリ量はごくわずかです。

于 2012-05-16T20:06:19.613 に答える
0

次のようにコーディングします。

saxParser.parse(new InputSource(new StringReader(xml));

StringReaderまず、周りに作成する必要がありますxml。これによりメモリ使用量が 2 倍になることはありません。StringReaderクラスは単に変数をラップxmlし、要求されたときに 1 文字ずつ返すだけです。

InputSourceはさらに薄く、提供されたReaderorをラップするだけInputStreamです。要するに:いいえ、Stringコピーされません。実装はかなり良いです。

于 2012-05-16T20:00:13.107 に答える
0

いいえ、文字列の 2 つのコピーを取得して、メモリを 2 倍にすることはできません。他のものはそのメモリを 2 倍にするかもしれませんが、文字列自体は複製されません。はい、visualVm と jconsole を接続して、メモリとスレッドの処理がどうなるかを確認する必要があります。

于 2012-05-16T20:01:09.730 に答える