14

If I take an XML file that is around 2kB on disk and load the contents as a String into memory in Java and then measure the object size it's around 33kB.

Why the huge increase in size?
If I do the same thing in C++ the resulting string object in memory is much closer to the 2kB.

To measure the memory in Java I'm using Instrumentation. For C++, I take the length of the serialized object (e.g string).

4

6 に答える 6

4

複数の要因が関係していると思います。まず第一に、Bruce Martin が言ったように、Java のオブジェクトにはオブジェクトごとに 16 バイトのオーバーヘッドがありますが、c++ にはありません。2 番目に、Java の文字列は 1 文字あたり 1 バイトではなく 2 バイトである可能性があります。3 番目に、Java は C++ の std::string よりも多くのメモリを文字列用に予約している可能性があります。

これらは、大きな違いが生じる可能性のあるアイデアにすぎないことに注意してください。

于 2013-05-24T07:14:08.070 に答える
4

XML ファイルに主に ASCII 文字が含まれ、それらを 1 バイトとして表すエンコーディングを使用すると仮定すると、Java は内部で UTF-16 を使用するため、メモリ内サイズは少なくとも 2 倍であると見なすことができます (いくつかの JVM について聞いたことがあります)。ただし、これを最適化してみてください)。これに加えて、いくつかのフィールドを持つ 2 つのオブジェクト (String インスタンスと内部 char 配列) のオーバーヘッドが追加され、IIRC 全体で約 40 バイトになります。

したがって、奇妙な JVM を使用していない限り、33kb の「オブジェクト サイズ」は間違いなく正しくありません。測定方法に問題があるはずです。

于 2013-05-24T07:14:24.880 に答える
1

String: String のメモリの増加は、内部の char 配列の増加を追跡します。ただし、String クラスはさらに 24 バイトのオーバーヘッドを追加します。サイズが 10 文字以下の空でない String の場合、有効なペイロード (文字ごとに 2 バイトと長さの 4 バイト) に対する追加のオーバーヘッド コストは、100 ~ 400% の範囲です。

詳細: Java のオブジェクトのメモリ消費量は?

于 2013-05-24T07:46:41.883 に答える
0

はい、GC を実行して、終了するまで時間を与える必要があります。ただ System.gc(); ループ内で totalMem() を出力します。また、文字列のサイズを測定し、プログラムに存在する可能性のある他のサービス オブジェクトではなく、文字列のサイズを測定するように、配列内に何百万もの文字列のコピーを作成することをお勧めします (空の配列サイズを測定してから、文字列で埋めます)。文字列だけでは 32 kb は使用できません。しかし、XML オブジェクトの階層化は可能です。

そうは言っても、Java の世界では誰もメモリ (およびキャッシュ ヒット) を気にしないという皮肉に抵抗できません。JIT は改善されており、場合によってはネイティブ C++ コードよりもパフォーマンスが優れていることがわかっています。したがって、メモリの最適化について気にする必要はありません。予備的な最適化は諸悪の根源です。

于 2013-05-24T07:19:40.777 に答える