はじめに
記事では、単純にメモリ使用量の文字列、配列、およびコレクションを分析するためにJOLツールの使用は、ここでより詳細な分析と導入を行うには、私はあなたが後でOOMの問題に遭遇することを願っていますときにもはや頭痛と涙が、章に従うことができる、それを開始します。
配列
まずJOLのコードと出力を見てみましょう:
//byte array
log.info("{}",ClassLayout.parseInstance("www.flydean.com".getBytes()).toPrintable());
出力結果:
INFO com.flydean.CollectionSize - [B object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 00) (1)
4 4 (object header) 00) (0)
8 4 (object header) 00) ( 4 (object header) 0f (000) ( byte [B.<elements> N/A
31 1 (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 0 bytes internal + 1 bytes external = 1 bytes total
この記事の結論は、COOPの圧縮オブジェクト・ポインタ技術をオンにして64ビットJVMを実行したことから導き出されたものであることに注意してください。
配列オブジェクトのオブジェクトヘッダのサイズが16バイト、配列内部のコンテンツの長さが15バイト、そして補数が1ビットであることがわかります。最終的に得られるサイズは32バイトです。
同様に、100個のオブジェクトの配列を計算すると、次のような結論になります:
配列に格納されているものが基本型でない場合、実際に格納されているのはそのオブジェクトの実行へのポインターで、サイズは4バイトです。
String
文字列は非常に特殊なオブジェクトで、一番下にバイト配列として格納されます。
JDK9では、Stringの基本的な記憶構造はchar[]であり、charは2バイトの記憶単位を取ることに注意してください。
ほとんどのStringはLatin-1文字エンコーディングで表現されるため、1バイトで済みます。
そのため、JDK9以降、文字列の基礎となるストレージはbyte[]になりました。
今回もJOLで分析:
//String
log.info("{}",ClassLayout.parseInstance("www.flydean.com").toPrintable());
出力結果:
INFO com.flydean.CollectionSize - java.lang.String object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 00) (5)
4 4 (object header) 00) (0)
8 4 (object header) 00) ( 4 byte[] String.value [, 2, , , , 1, int String.hash 0
20 1 byte String.coder 0
21 1 boolean String.hashIsZero false
22 2 (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 2 bytes external = 2 bytes total
Stringのオブジェクト・ヘッダが12バイトであることがわかり、次にバイト配列への4バイトのポインタを追加します。ハッシュ、コーダー、hasIsZero属性を追加すると、最終的なサイズは24バイトになります。
ここではJDK14のStringバージョンを使っていますが、バージョンによって異なるかもしれません。
もちろん、これはこのStringオブジェクトのサイズであって、基礎となる配列のサイズではありません。
を使用して、String オブジェクトの真のサイズを計算します:
文字列オブジェクトのサイズ + バイト配列のサイズ = 24 + 32 = 56 バイト。
ArrayList
非常に単純なArrayListを構築します:
//Array List
log.info("{}",ClassLayout.parseInstance(new ArrayList()).toPrintable());
出力結果:
INFO com.flydean.CollectionSize - java.util.ArrayList object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 00) (5)
4 4 (object header) 00) (0)
8 4 (object header) 00) ( 4 int AbstractList.modCount 0
16 4 int ArrayList.size 0
20 4 java.lang.Object[] ArrayList.elementData []
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
これを視覚化するために図を描いてください:
ここでmodCountとsizeの初期値はどちらも0です。
HashMap
記事の長さの関係で、ここではコードを列挙せず、写真だけをアップします:
HashSet
LinkedList
treeMap
もっと複雑なTreeMapを見てみましょう:
まとめ
この記事では、メモリ内のコレクション・オブジェクト、配列、文字列の使い方を図解します。
もし興味があれば、下に計算結果を書いて返信してください。
この記事を書いた人: Flydean procedure those things
この記事へのリンク
出典:フライディーンブログ