Download - Metaspace
![Page 1: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/1.jpg)
MetaspaceをOpenJDK実装から見てみよ
う!末永 恭正 @YaSuenag
#ccc_r25
![Page 2: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/2.jpg)
おことわり この資料は 2014/05/17 時点の JDK8u/
jdk8u-dev/hotspot ( changeset 382a82b0a3e7 : jdk8u20-b14 )の内容を基に記載しています。
Oracle と Java は、 Oracle Corporation 及びその子会社、関連会社の米国及びその他の国における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合があります。
![Page 3: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/3.jpg)
自己紹介 末永 恭正(すえなが やすまさ) @YaSuenag
某 SIer で Java やってるサンデープログラマー
OpenJDK Author ( jdk9 ) IcedTea Committer
HeapStats 作ってますhttp://icedtea.classpath.org/wiki/HeapStats/jp
![Page 4: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/4.jpg)
Metaspaceって、何?
![Page 5: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/5.jpg)
Metaspace
Permanent 世代の代わりに導入されたメタデータ管理の仕組みJEP 122: Remove the Permanent Generation
http://openjdk.java.net/jeps/122
“HotRockit” の一環
Perm 世代をネイティブメモリに追い出す
![Page 6: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/6.jpg)
扱うデータ JVM 実装で MetaspaceObj クラスを継承して
いるものが Metaspace で扱われるClassType
○ 純粋なクラス情報NonClassType
○ ClassType 以外の情報○ シンボル情報やメソッドの最適化に必要な情報など
![Page 7: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/7.jpg)
MetaspaceObj の一覧
![Page 8: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/8.jpg)
Metaspace の種類StandardMetaspaceType 通常の Metaspace
BootMetaspaceType ブートストラップクラスローダ専用
ROMetaspaceType クラス情報ダンプ時に使用される Metaspace( -XX:+DumpSharedSpaces )
ReadWriteMetaspaceType
AnonymousMetaspaceType 匿名クラス専用( InvokeDynamic )
ReflectionMetaspaceType defineClass 専用(リフレクションなどの動的定義クラス)
![Page 9: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/9.jpg)
メモリレイアウト
![Page 10: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/10.jpg)
![Page 11: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/11.jpg)
ClassLoader とVirtualSpace
ClassLoader
仮想メモリ空間VirtualSpaceList
VirtualSpace
VirtualSpace
:VirtualSpace
VirtualSpace
:
ClassLoader
メタデータ用のバラバラの空間を仮想的に 1 つに=Metaspace
VirtualSpaceCompressedClassSpace !?
![Page 12: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/12.jpg)
CompressedClassSpace
圧縮 Oop が利用可能な状況でのみ使用できる、クラス情報に特化したメモリ空間UseCompressedOops が有効であることが必須
○ 最大 Java ヒープサイズが 32GB 以下であること UseCompressedClassPointers でコントロー
ル可能
![Page 13: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/13.jpg)
圧縮 Oop ? LP64 向け HotSpot でのみ利用可能なメモリ
使用量削減の仕組み 64bit ポインタを、ベースアドレスからのオ
フセットを用いてムリヤリ 32bit で表現
![Page 14: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/14.jpg)
どういうこと? LP64 のメモリアライメントは 8byte
ObjectAlignmentInBytes でコントロール○ デフォルト: 8
つまり、下位 3bit はゼロで埋められている3bit 右シフトしても情報欠損が起きない!
Java ヒープや CompressedClassSpace は連続空間そこの上にアロケートされるメモリは、すべて開始
アドレスからのオフセットで表現可能!
![Page 15: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/15.jpg)
プログラム的に表すと…http://www.oracle.com/technetwork/jp/articles/java/compressedoops-427542-ja.html
圧縮 Oop ( narrowOop )は符号なし 32bit で表現されるのでuint_max ( 4GB ) << 3 = 4GB×23 = 32GB
圧縮できる上限
![Page 16: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/16.jpg)
Metaspaceの成長
![Page 17: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/17.jpg)
Metaspace の成長= VirtualSpaceList の成長
=VirtualSpace の追加 成長度合い
チャンクサイズで決まります
![Page 18: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/18.jpg)
Metaspace とチャンクサイズ
![Page 19: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/19.jpg)
チャンクサイズはイジれません…
HotSpot の 1 ワード: LP64 なら 8 バイト、それ以外なら 4 バイト
対数( log )です
![Page 20: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/20.jpg)
ここまでのまとめ Metaspace は 1 クラスローダにつき 1 つ割り
当てられる Metaspace は連続したメモリ空間ではない Metaspace で扱われる情報は大きく 2 種類
クラス情報それ以外
Metaspace には 6 つの種類が存在する LP64 環境で Java ヒープサイズが 32GB 以下
の場合は CompressedClassSpace が作られる
![Page 21: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/21.jpg)
都市伝説(?):MetaspaceではOutOfMemoryErrorは起きない?
![Page 22: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/22.jpg)
Metaspace でもOutOfMemoryError は起きます!
![Page 23: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/23.jpg)
実証コードimport java.nio.file.*;import java.util.jar.*;
public class MetaFlood{
public static void main(String[] args) throws Exception{ Path rtjar_path = FileSystems.getDefault().getPath( System.getProperty("java.home"), "lib", "rt.jar");
try(JarFile rtjar = new JarFile(rtjar_path.toFile())){ rtjar.stream().filter(e -> !e.isDirectory()) .map(e -> e.getName()) .filter(n -> n.endsWith(".class")) .map(n -> n.substring(0, n.length() - 6).replace('/', '.')) .forEach(n -> { System.out.println(n); try{ ClassLoader.getSystemClassLoader().loadClass(n); } catch(ClassNotFoundException ex){} catch(OutOfMemoryError oome){ System.out.println(oome.toString()); throw oome; } }); }
}
}
![Page 24: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/24.jpg)
OOME を起こしてみる
$ /usr/local/jdk1.8.0_05/bin/java -XX:CompressedClassSpaceSize=1m MetaFlood :java.lang.OutOfMemoryError: Compressed class spaceException in thread "main“ :
$ /usr/local/jdk1.8.0_05/bin/java -XX:-UseCompressedClassPointers \ -XX:MaxMetaspaceSize=5m MetaFlood :java.lang.OutOfMemoryError: MetaspaceException in thread "main“ :
その1: CompressedClassSpace 溢れ
その2: Metaspace 溢れ
![Page 25: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/25.jpg)
MetaspaceとGC
![Page 26: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/26.jpg)
Permanent との違い Metaspace が GC されることはありません
クラスローダが破棄されると、関連するMetaspace が削除されます
FullGC 後に Metaspace 容量の調整を行います拡張 or 削減ここでは閾値の変更のみを行い、実際のメモリ伸
縮は行いません
![Page 27: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/27.jpg)
MetaspaceGC
![Page 28: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/28.jpg)
Metaspace 起因の GC が起こるまで
1. Metaspace からメモリを取ろうとするi. 今あるメモリから取ろうとするii. Metaspace を拡張して取ろうとする
2. GC を起こすi. 使われていないクラスローダを GC で回収し、
できるだけ空き Metaspace を増やすii. Metaspace を拡張して取ろうとする
~通常はここまでで Metaspace がとれる~
→OutOfMemoryError
![Page 29: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/29.jpg)
GC ログの例[Full GC (Metadata GC Threshold) [PSYoungGen: 496K->0K(2560K)] [ParOldGen: 388K->836K(6656K)] 884K->836K(9216K), [Metaspace: 7292K->7292K(9216K)], 0.0123187 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
[Full GC (Last ditch collection) [PSYoungGen: 0K->0K(2560K)] [ParOldGen: 836K->792K(6656K)] 836K->792K(9216K), [Metaspace: 7292K->7292K(9216K)], 0.0134180 secs] [Times: user=0.04 sys=0.00, real=0.02 secs]
※見やすく改行しています
Metaspace が足りなくてGC が発生
GC してもまだ足りないため
最後の悪あがき
![Page 30: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/30.jpg)
「最後の悪あがき」とは? ソフト参照も回収対象にし、できる限りクラス
ローダを回収しようとします
![Page 31: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/31.jpg)
どうチェックする?Metaspace使用量
![Page 32: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/32.jpg)
5 つの手段1. ツール
jstatjcmdjconsoleVisualVM
2. JMX
3. GC ログ4. NMT
5. HeapStats
![Page 33: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/33.jpg)
jstat
-gc などが使えます(単位は全部 KB )MC : Metaspace CapacityMU : Metaspace UsedCCSC: Compressed Class Space Capacity CCSU: Compressed Class Space Used
-gcmetacapacity というオプションもありますメタスペースサイズと GC回数・時間の取得用
$ /usr/local/jdk1.8.0_05/bin/jstat -gc 7831… MC MU CCSC CCSU …… 4864.0 2377.7 512.0 258.0 …
![Page 34: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/34.jpg)
jcmd
PerfCounter.print で細かく見れますsun.gc.metaspacesun.gc.compressedclassspace
$ /usr/local/jdk1.8.0_05/bin/jcmd 7831 PerfCounter.print :sun.gc.compressedclassspace.capacity=524288sun.gc.compressedclassspace.maxCapacity=1073741824sun.gc.compressedclassspace.minCapacity=0sun.gc.compressedclassspace.used=264208 :sun.gc.metaspace.capacity=4980736sun.gc.metaspace.maxCapacity=1082130432sun.gc.metaspace.minCapacity=0sun.gc.metaspace.used=2434808 :
![Page 35: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/35.jpg)
jconsole
各メモリプールから確認できます
![Page 36: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/36.jpg)
VisualVM
Metaspace全体の確認ができます
![Page 37: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/37.jpg)
JMX
各メモリプールがあります
![Page 38: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/38.jpg)
GC ログ Permだったところが Metaspace に変わって
います$ /usr/local/jdk1.8.0_05/bin/java -XX:+PrintGCDetails SystemGC :[Full GC (System.gc()) [PSYoungGen: 368K->0K(1024K)] [ParOldGen: 8K->251K(59904K)] 376K->251K(60928K), [Metaspace: 2377K->2377K(1056768K)], 0.0047055 secs][Times: user=0.01 sys=0.00, real=0.00 secs] : ※見やすく改行しています
![Page 39: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/39.jpg)
Native Memory Tracking (NMT)
細かい情報を簡単に知りたいときに最適 -XX:NativeMemoryTracking=[summary|detail] 取り方は 2 種類
-XX:+UnlockDiagnosticVMOptions と-XX:+PrintNMTStatistics で java終了時に取得
jcmd <PID> VM.native_memory で外側から取得 Metaspace は” Class” の部分です
![Page 40: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/40.jpg)
jcmd VM.native_memory
$ /usr/local/jdk1.8.0_05/bin/jcmd 8858 VM.native_memory8858:
Native Memory Tracking:
Total: reserved=2330153KB, committed=135365KB :- Class (reserved=1062006KB, committed=10102KB) (classes #374) (malloc=5238KB, #153) (mmap: reserved=1056768KB, committed=4864KB) :
インスタンスクラス数
![Page 41: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/41.jpg)
HeapStats
1.1系を使ってください 閾値監視( SNMP Trap送信)もできます
ココ
![Page 42: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/42.jpg)
注意 Metaspace の値は CompressedClassSpace
の値も含む、全体的な値です。CompressedClassSpace Metaspace⊆
NonClassType な Metaspace を見たい場合は、Metaspace から CompressedClassSpace分を引いてください。
![Page 43: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/43.jpg)
Metaspace関連オプション
![Page 44: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/44.jpg)
Metaspace 関連オプション( -XX )オプション 意味 デフォルトMinMetaspaceExpansion Metaspace の最小拡張単
位256KB
MinMetaspaceFreeRatio GC 後の最小フリー量のパーセンテージ
40
MaxMetaspaceFreeRatio GC 後の最大フリー量のパーセンテージ
70
MaxMetaspaceExpansion Metaspace の最大拡張単位
4MB
![Page 45: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/45.jpg)
Metaspace 関連オプション( -XX )オプション 意味 デフォルトUseLargePagesInMetaspace Metaspace にラージペー
ジを使うか?( UseLargePages 必須)
false
TraceMetadataHumongousAllocation 大きなオブジェクトをMetaspace にアロケートするのをトレースする
false
InitialBootClassLoaderMetaspaceSize ブートクラスローダ用Metaspace の初期値
LP64 : 4MB
それ以外:2200KB
MetaspaceSize Metaspace をリサイズさせるための閾値
環境依存
MaxMetaspaceSize 最大 Metaspace サイズ unsigned long最大値
CompressedClassSpaceSize CompressedClassSpaceのサイズ
1GB
![Page 46: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/46.jpg)
-XX:MetaspaceSize ではMetaspace の初期サイズを
指定できません!
![Page 47: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/47.jpg)
hotspot-gc-dev に質問してみたhttp://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2014-April/009853.html
JIRA にも登録しました: JDK-8039867: Incorrect description: -XX:MetaspaceSize https://bugs.openjdk.java.net/browse/JDK-8039867
![Page 48: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/48.jpg)
チューニング(?)
![Page 49: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/49.jpg)
オプションをつける前に… Metaspace は連続空間ではない 1 クラスローダ 1 メタスペース
ブートストラップ以外のクラスローダの初期サイズは変更できない○ InitialBootClassLoaderMetaspaceSize (デフォルト
4MB ) CompressedClassSpace はクラス情報「だけ」
シンボルやメソッドプロファイル情報などは別領域 長時間動作させていれば、 Metaspace 使用量はあ
る程度安定してくる(はず)動的ロードをガンガン行う場合はワカラナイ…
![Page 50: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/50.jpg)
一番注意すべきオプションCompressedClassSpaceSize
JDK7u55 : VmSize: 2153520 kB
JDK8u5 : VmSize: 3390320 kB
約 1GB の差!
オプションを何もつけずに起動したときの仮想メモリ使用量( VSZ )
![Page 51: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/51.jpg)
なぜ 1GB も差が? AMD64 な JDK7 では MaxPermSize の初期値
が 64MB ( jdk7u-dev の HotSpot の場合)Perm目的で 64MB しかリザーブしない
○ MaxPermSize はプラットフォームや HotSpot VM の種類によりデフォルト値が異なります
CompressedClassSpace のデフォルトは 1GB1GB リザーブしてしまう!!
デフォルトのまま使うときはオーバーコミットに注意しましょう!
![Page 52: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/52.jpg)
MaxMetaspaceSize
青天井!OS に殺されるかも
…
![Page 53: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/53.jpg)
古の情報http://hg.openjdk.java.net/hsx/hotspot-rt/hotspot/diff/740e263c80c6/src/share/vm/runtime/arguments.cpp#l1.83
昔は 1 クラス情報= 1KB とみなしていました CompressedClassSpace をデフォルトで 100MB
に昔は ClassMetaspaceSize というオプションでした100,000 クラスはロードできるよ!という話
![Page 54: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/54.jpg)
1 クラスあたりの占有サイズ フィールド数、メソッド数によって異なります 一概に「だいたい xx バイト」と表現できません
実測一番!
![Page 55: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/55.jpg)
と、いうわけで…
-XX:MaxMetaspaceSize= そこそこ-XX:CompressedClassSpaceSize=100m
※責任はもちません
-XX:MaxMetaspaceSize= そこそこ
①-Xmx32g 以下の場合
②-Xmx32g超えの場合
③もう何も気にしたくない場合
-XX:-UseCompressedClassPointers
![Page 56: Metaspace](https://reader036.vdocuments.pub/reader036/viewer/2022062319/55660c2cd8b42aa6628b516c/html5/thumbnails/56.jpg)
?