最近、文字列のメモリ割り当てについて多くのことを読みましたが、Java 8と同じ場合に詳細を見つけることができません。
"Alexandru Tanasescu"
のような文字列は、Java 8で使用しますか?64ビットバージョンを使用します。
最小文字列メモリ使用量:
(bytes) = 8 * (int) ((((no chars) * 2) + 45) / 8)
そう
80 = 8 * (int) ((((19) * 2) + 45) / 8)
文字列のメモリ使用量を理解する(- [〜#〜] source [〜#〜] )
上記の計算を理解するには、まずStringオブジェクトのフィールドを調べる必要があります。文字列には次のものが含まれます。
- 実際の文字を含むchar配列(つまり、別個のオブジェクト)。
- 文字列が始まる配列への整数オフセット。
- ストリングの長さ。
- ハッシュコードのキャッシュ計算用の別の整数。
つまり、文字列に文字が含まれていない場合でも、char配列参照に4バイト、3つのintフィールドに3 * 4 = 12バイト、および8バイトのオブジェクトヘッダーが必要です。これにより24バイトが得られます(これは8の倍数であるため、これまで「パディング」バイトは不要です)。
次に、(空の)char配列には、さらに12バイト(配列には長さを格納するための余分な4バイトが必要です)に加えて、この場合、char配列オブジェクトが使用するメモリを16.したがって、合計で、空の文字列は40バイトを使用します。
String
にたとえば19文字が含まれている場合、Stringオブジェクト自体には24バイトが必要です。しかし現在、char配列には12バイトのヘッダーと、17文字に対して19 * 2 = 38バイトが必要です。 12 + 38 = 50は8の倍数ではないため、次の8の倍数(56)に切り上げる必要もあります。したがって、全体として、19文字のString
は56 + 24 = 80バイトを使用します。
Java 8には
offset
とlength
はもうありません。hash
およびCharArray
のみ。
@ Thomas Jungblut
そのため、Java8では、文字列のメモリを計算する方法は同じですが、offset
とlength
がないため、8バイトを差し引く必要があります。
Oracle Java 8個のソースを見ると、次のものがあります。
char value[]
と int hash
。 char
は2バイトで、int
は4バイトです。
したがって、答えはyourstring.length
* 2 + 4?
いいえ。すべてのオブジェクトにオーバーヘッドがありました。たとえば、配列にはその次元が格納されます。そして、配列(オブジェクト)と文字列の両方が、それらに関する情報を格納するガベージコレクターから余分なメモリを負担します。
各JREとJDKにはオブジェクトオーバーヘッドのサイズに対する義務がないため、これを計算する信頼できる方法はありません。
「Alexandru Tanasescu」は104バイトを使用します。これはサイズを取得する方法です
long m0 = Runtime.getRuntime().freeMemory();
String s = new String("Alexandru Tanasescu");
long m1 = Runtime.getRuntime().freeMemory();
System.out.println(m0 - m1);
注:-XX:-UseTLABオプションで実行します
次のJEPによると: http://openjdk.Java.net/jeps/254
Stringクラスの現在の実装では、文字ごとに2バイト(16ビット)を使用して、文字をchar配列に格納します。
Java SE 9ではこれは変更される可能性があります。
ただし、これはJSRではなくJEPであるため(実装についても言及しています)、これは実装固有のものであり、JLSによって定義されていないことを理解しています。