Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
末永 恭正 @YaSuenag
#ccc_r25
おことわり
 この資料は2014/05/17時点の
JDK8u/jdk8u-dev/hotspot(changeset
382a82b0a3e7:jdk8u20-b14)の内容を
基に記載しています。
OracleとJavaは、Oracle ...
自己紹介
 末永 恭正(すえなが やすまさ) @YaSuenag
 某SIerでJavaやってるサンデープログラマー
 OpenJDK Author(jdk9)
 IcedTea Committer
 HeapStats作ってます
h...
Metaspace
 Permanent世代の代わりに導入されたメタ
データ管理の仕組み
 JEP 122: Remove the Permanent Generation
http://openjdk.java.net/jeps/122
...
扱うデータ
 JVM実装でMetaspaceObjクラスを継承して
いるものがMetaspaceで扱われる
 ClassType
○ 純粋なクラス情報
 NonClassType
○ ClassType以外の情報
○ シンボル情報やメソッ...
MetaspaceObjの一覧
Metaspaceの種類
StandardMetaspaceType 通常のMetaspace
BootMetaspaceType ブートストラップクラスローダ
専用
ROMetaspaceType クラス情報ダンプ時に使用され
るMetasp...
ClassLoaderとVirtualSpace
Class
Loader
仮想メモリ空間VirtualSpaceList
VirtualSpace
VirtualSpace
:
VirtualSpace
VirtualSpace
:
Clas...
CompressedClassSpace
 圧縮Oopが利用可能な状況でのみ使用できる、
クラス情報に特化したメモリ空間
 UseCompressedOopsが有効であることが必須
○ 最大Javaヒープサイズが32GB以下であること
 ...
圧縮Oop?
 LP64向けHotSpotでのみ利用可能なメモリ使
用量削減の仕組み
 64bitポインタを、ベースアドレスからのオフ
セットを用いてムリヤリ32bitで表現
どういうこと?
 LP64のメモリアライメントは8byte
 ObjectAlignmentInBytesでコントロール
○ デフォルト:8
 つまり、下位3bitはゼロで埋められている
 3bit右シフトしても情報欠損が起きない!
...
プログラム的に表すと…
http://www.oracle.com/technetwork/jp/articles/java/compressedoops-427542-ja.html
圧縮Oop(narrowOop)は符号なし32bitで表現...
Metaspaceの成長
= VirtualSpaceListの成長
=VirtualSpaceの追加
 成長度合い
 チャンクサイズで決まります
Metaspaceとチャンクサイズ
チャンクサイズはイジれません
…
HotSpotの1ワード:LP64なら8バイト、それ以外なら4バイト
対数(log)です
ここまでのまとめ
 Metaspaceは1クラスローダにつき1つ割り当
てられる
 Metaspaceは連続したメモリ空間ではない
 Metaspaceで扱われる情報は大きく2種類
 クラス情報
 それ以外
 Metaspaceには...
Metaspaceでも
OutOfMemoryErrorは起きます!
実証コード
import java.nio.file.*;
import java.util.jar.*;
public class MetaFlood{
public static void main(String[] args) throw...
OOMEを起こしてみる
$ /usr/local/jdk1.8.0_05/bin/java -XX:CompressedClassSpaceSize=1m MetaFlood
:
java.lang.OutOfMemoryError: Comp...
Permanentとの違い
 MetaspaceがGCされることはありません
 クラスローダが破棄されると、関連する
Metaspaceが削除されます
 FullGC後にMetaspace容量の調整を行います
 拡張 or 削減
 こ...
MetaspaceGC
Metaspace起因のGCが起こるま
で
1. Metaspaceからメモリを取ろうとする
i. 今あるメモリから取ろうとする
ii. Metaspaceを拡張して取ろうとする
2. GCを起こす
i. 使われていないクラスローダをGCで回収...
GCログの例
[Full GC (Metadata GC Threshold)
[PSYoungGen: 496K->0K(2560K)]
[ParOldGen: 388K->836K(6656K)] 884K->836K(9216K),
[M...
「最後の悪あがき」とは?
 ソフト参照も回収対象にし、できる限りクラス
ローダを回収しようとします
5つの手段
1. ツール
 jstat
 jcmd
 jconsole
 VisualVM
2. JMX
3. GCログ
4. NMT
5. HeapStats
jstat
 -gcなどが使えます(単位は全部KB)
 MC:Metaspace Capacity
 MU:Metaspace Used
 CCSC: Compressed Class Space Capacity
 CCSU: Co...
jcmd
 PerfCounter.printで細かく見れます
 sun.gc.metaspace
 sun.gc.compressedclassspace
$ /usr/local/jdk1.8.0_05/bin/jcmd 7831 P...
jconsole
 各メモリプールから確認できます
VisualVM
 Metaspace全体の確認ができます
JMX
 各メモリプールがあります
GCログ
 PermだったところがMetaspaceに変わって
います
$ /usr/local/jdk1.8.0_05/bin/java -XX:+PrintGCDetails SystemGC
:
[Full GC (System.gc(...
Native Memory Tracking (NMT)
 細かい情報を簡単に知りたいときに最適
 -XX:NativeMemoryTracking=[summary|detail]
 取り方は2種類
 -XX:+UnlockDiagn...
jcmd VM.native_memory
$ /usr/local/jdk1.8.0_05/bin/jcmd 8858 VM.native_memory
8858:
Native Memory Tracking:
Total: reserve...
HeapStats
 1.1系を使ってください
 閾値監視(SNMP Trap送信)もできます
ココ
注意
 Metaspaceの値はCompressedClassSpaceの
値も含む、全体的な値です。
 CompressedClassSpace⊆Metaspace
 NonClassTypeなMetaspaceを見たい場合は、
Met...
Metaspace関連オプション(-
XX)オプション 意味 デフォルト
MinMetaspaceExpansion Metaspaceの最小拡張単
位
256KB
MinMetaspaceFreeRatio GC後の最小フリー量の
パーセンテ...
Metaspace関連オプション(-
XX)オプション 意味 デフォルト
UseLargePagesInMetaspace Metaspaceにラージペー
ジを使うか?
(UseLargePages必須)
false
TraceMetadata...
-XX:MetaspaceSizeでは
Metaspaceの初期サイズを
指定できません!
hotspot-gc-devに質問してみた
http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2014-April/009853.html
JIRAにも登録しました:
JDK-80398...
オプションをつける前に…
 Metaspaceは連続空間ではない
 1クラスローダ1メタスペース
 ブートストラップ以外のクラスローダの初期サイズは
変更できない
○ InitialBootClassLoaderMetaspaceSize...
一番注意すべきオプション
CompressedClassSpaceSize
JDK7u55:
VmSize: 2153520 kB
JDK8u5:
VmSize: 3390320 kB
約1GBの差!
オプションを何もつけずに起動したときの仮想...
なぜ1GBも差が?
 AMD64なJDK7ではMaxPermSizeの初期値が
64MB(jdk7u-devのHotSpotの場合)
 Perm目的で64MBしかリザーブしない
○ MaxPermSizeはプラットフォームやHotSpot ...
MaxMetaspaceSize
青天井!
OSに殺されるかも…
古の情報
http://hg.openjdk.java.net/hsx/hotspot-rt/hotspot/diff/740e263c80c6/src/share/vm/runtime/arguments.cpp#l1.83
 昔は1クラス...
1クラスあたりの占有サイズ
 フィールド数、メソッド数によって異なります
 一概に「だいたいxxバイト」と表現できません
実測一番!
と、いうわけで…
-XX:MaxMetaspaceSize=そこそこ
-XX:CompressedClassSpaceSize=100m
※責任はもちません
-XX:MaxMetaspaceSize=そこそこ
①-Xmx32g以下の場合
②-X...
Metaspace
Metaspace
Metaspace
Metaspace
Metaspace
Metaspace
Metaspace
Metaspace
Metaspace
Metaspace
Upcoming SlideShare
Loading in …5
×

Metaspace

12,723 views

Published on

JJUG CCC 2014 Spring資料

Published in: Technology

Metaspace

  1. 1. 末永 恭正 @YaSuenag #ccc_r25
  2. 2. おことわり  この資料は2014/05/17時点の JDK8u/jdk8u-dev/hotspot(changeset 382a82b0a3e7:jdk8u20-b14)の内容を 基に記載しています。 OracleとJavaは、Oracle Corporation及びその子会社、関連会社の米国及びその他の国における登録商標です。 文中の社名、商品名等は各社の商標または登録商標である場合があります。
  3. 3. 自己紹介  末永 恭正(すえなが やすまさ) @YaSuenag  某SIerでJavaやってるサンデープログラマー  OpenJDK Author(jdk9)  IcedTea Committer  HeapStats作ってます http://icedtea.classpath.org/wiki/HeapStats/jp
  4. 4. Metaspace  Permanent世代の代わりに導入されたメタ データ管理の仕組み  JEP 122: Remove the Permanent Generation http://openjdk.java.net/jeps/122 “HotRockit”の一環 Perm世代をネイティブ メモリに追い出す
  5. 5. 扱うデータ  JVM実装でMetaspaceObjクラスを継承して いるものがMetaspaceで扱われる  ClassType ○ 純粋なクラス情報  NonClassType ○ ClassType以外の情報 ○ シンボル情報やメソッドの最適化に必要な情報など
  6. 6. MetaspaceObjの一覧
  7. 7. Metaspaceの種類 StandardMetaspaceType 通常のMetaspace BootMetaspaceType ブートストラップクラスローダ 専用 ROMetaspaceType クラス情報ダンプ時に使用され るMetaspace (-XX:+DumpSharedSpaces) ReadWriteMetaspaceType AnonymousMetaspaceType 匿名クラス専用 (InvokeDynamic) ReflectionMetaspaceType defineClass専用 (リフレクションなどの動的定義クラス)
  8. 8. ClassLoaderとVirtualSpace Class Loader 仮想メモリ空間VirtualSpaceList VirtualSpace VirtualSpace : VirtualSpace VirtualSpace : Class Loader メタデータ用の バラバラの空間を 仮想的に1つに =Metaspace VirtualSpace Compressed ClassSpace !?
  9. 9. CompressedClassSpace  圧縮Oopが利用可能な状況でのみ使用できる、 クラス情報に特化したメモリ空間  UseCompressedOopsが有効であることが必須 ○ 最大Javaヒープサイズが32GB以下であること  UseCompressedClassPointersでコントロー ル可能
  10. 10. 圧縮Oop?  LP64向けHotSpotでのみ利用可能なメモリ使 用量削減の仕組み  64bitポインタを、ベースアドレスからのオフ セットを用いてムリヤリ32bitで表現
  11. 11. どういうこと?  LP64のメモリアライメントは8byte  ObjectAlignmentInBytesでコントロール ○ デフォルト:8  つまり、下位3bitはゼロで埋められている  3bit右シフトしても情報欠損が起きない!  JavaヒープやCompressedClassSpaceは連続 空間  そこの上にアロケートされるメモリは、すべて開始 アドレスからのオフセットで表現可能!
  12. 12. プログラム的に表すと… http://www.oracle.com/technetwork/jp/articles/java/compressedoops-427542-ja.html 圧縮Oop(narrowOop)は符号なし32bitで表現されるので uint_max(4GB)<< 3 = 4GB×23 = 32GB 圧縮できる上限
  13. 13. Metaspaceの成長 = VirtualSpaceListの成長 =VirtualSpaceの追加  成長度合い  チャンクサイズで決まります
  14. 14. Metaspaceとチャンクサイズ
  15. 15. チャンクサイズはイジれません … HotSpotの1ワード:LP64なら8バイト、それ以外なら4バイト 対数(log)です
  16. 16. ここまでのまとめ  Metaspaceは1クラスローダにつき1つ割り当 てられる  Metaspaceは連続したメモリ空間ではない  Metaspaceで扱われる情報は大きく2種類  クラス情報  それ以外  Metaspaceには6つの種類が存在する  LP64環境でJavaヒープサイズが32GB以下の 場合はCompressedClassSpaceが作られる
  17. 17. Metaspaceでも OutOfMemoryErrorは起きます!
  18. 18. 実証コード 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; } }); } } }
  19. 19. OOMEを起こしてみる $ /usr/local/jdk1.8.0_05/bin/java -XX:CompressedClassSpaceSize=1m MetaFlood : java.lang.OutOfMemoryError: Compressed class space Exception in thread "main“ : $ /usr/local/jdk1.8.0_05/bin/java -XX:-UseCompressedClassPointers -XX:MaxMetaspaceSize=5m MetaFlood : java.lang.OutOfMemoryError: Metaspace Exception in thread "main“ : その1:CompressedClassSpace溢れ その2:Metaspace溢れ
  20. 20. Permanentとの違い  MetaspaceがGCされることはありません  クラスローダが破棄されると、関連する Metaspaceが削除されます  FullGC後にMetaspace容量の調整を行います  拡張 or 削減  ここでは閾値の変更のみを行い、実際のメモリ伸 縮は行いません
  21. 21. MetaspaceGC
  22. 22. Metaspace起因のGCが起こるま で 1. Metaspaceからメモリを取ろうとする i. 今あるメモリから取ろうとする ii. Metaspaceを拡張して取ろうとする 2. GCを起こす i. 使われていないクラスローダをGCで回収し、 できるだけ空きMetaspaceを増やす ii. Metaspaceを拡張して取ろうとする ~通常はここまででMetaspaceがとれる~ →OutOfMemoryError
  23. 23. 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しても まだ足りないため 最後の悪あがき
  24. 24. 「最後の悪あがき」とは?  ソフト参照も回収対象にし、できる限りクラス ローダを回収しようとします
  25. 25. 5つの手段 1. ツール  jstat  jcmd  jconsole  VisualVM 2. JMX 3. GCログ 4. NMT 5. HeapStats
  26. 26. jstat  -gcなどが使えます(単位は全部KB)  MC:Metaspace Capacity  MU:Metaspace Used  CCSC: 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 …
  27. 27. jcmd  PerfCounter.printで細かく見れます  sun.gc.metaspace  sun.gc.compressedclassspace $ /usr/local/jdk1.8.0_05/bin/jcmd 7831 PerfCounter.print : sun.gc.compressedclassspace.capacity=524288 sun.gc.compressedclassspace.maxCapacity=1073741824 sun.gc.compressedclassspace.minCapacity=0 sun.gc.compressedclassspace.used=264208 : sun.gc.metaspace.capacity=4980736 sun.gc.metaspace.maxCapacity=1082130432 sun.gc.metaspace.minCapacity=0 sun.gc.metaspace.used=2434808 :
  28. 28. jconsole  各メモリプールから確認できます
  29. 29. VisualVM  Metaspace全体の確認ができます
  30. 30. JMX  各メモリプールがあります
  31. 31. 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] : ※見やすく改行しています
  32. 32. Native Memory Tracking (NMT)  細かい情報を簡単に知りたいときに最適  -XX:NativeMemoryTracking=[summary|detail]  取り方は2種類  -XX:+UnlockDiagnosticVMOptions と -XX:+PrintNMTStatistics でjava終了時に取得  jcmd <PID> VM.native_memoryで外側から取得  Metaspaceは”Class”の部分です
  33. 33. jcmd VM.native_memory $ /usr/local/jdk1.8.0_05/bin/jcmd 8858 VM.native_memory 8858: Native Memory Tracking: Total: reserved=2330153KB, committed=135365KB : - Class (reserved=1062006KB, committed=10102KB) (classes #374) (malloc=5238KB, #153) (mmap: reserved=1056768KB, committed=4864KB) : インスタンス クラス数
  34. 34. HeapStats  1.1系を使ってください  閾値監視(SNMP Trap送信)もできます ココ
  35. 35. 注意  Metaspaceの値はCompressedClassSpaceの 値も含む、全体的な値です。  CompressedClassSpace⊆Metaspace  NonClassTypeなMetaspaceを見たい場合は、 MetaspaceからCompressedClassSpace分を 引いてください。
  36. 36. Metaspace関連オプション(- XX)オプション 意味 デフォルト MinMetaspaceExpansion Metaspaceの最小拡張単 位 256KB MinMetaspaceFreeRatio GC後の最小フリー量の パーセンテージ 40 MaxMetaspaceFreeRatio GC後の最大フリー量の パーセンテージ 70 MaxMetaspaceExpansion Metaspaceの最大拡張単 位 4MB
  37. 37. Metaspace関連オプション(- XX)オプション 意味 デフォルト UseLargePagesInMetaspace Metaspaceにラージペー ジを使うか? (UseLargePages必須) false TraceMetadataHumongousAllocation 大きなオブジェクトを Metaspaceにアロケート するのをトレースする false InitialBootClassLoaderMetaspaceSize ブートクラスローダ用 Metaspaceの初期値 LP64:4MB それ以外: 2200KB MetaspaceSize Metaspaceをリサイズさ せるための閾値 環境依存 MaxMetaspaceSize 最大Metaspaceサイズ unsigned long 最大値 CompressedClassSpaceSize CompressedClassSpace のサイズ 1GB
  38. 38. -XX:MetaspaceSizeでは Metaspaceの初期サイズを 指定できません!
  39. 39. 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
  40. 40. オプションをつける前に…  Metaspaceは連続空間ではない  1クラスローダ1メタスペース  ブートストラップ以外のクラスローダの初期サイズは 変更できない ○ InitialBootClassLoaderMetaspaceSize(デフォルト4MB)  CompressedClassSpaceはクラス情報「だけ」  シンボルやメソッドプロファイル情報などは別領域  長時間動作させていれば、Metaspace使用量はあ る程度安定してくる(はず)  動的ロードをガンガン行う場合はワカラナイ…
  41. 41. 一番注意すべきオプション CompressedClassSpaceSize JDK7u55: VmSize: 2153520 kB JDK8u5: VmSize: 3390320 kB 約1GBの差! オプションを何もつけずに起動したときの仮想 メモリ使用量(VSZ)
  42. 42. なぜ1GBも差が?  AMD64なJDK7ではMaxPermSizeの初期値が 64MB(jdk7u-devのHotSpotの場合)  Perm目的で64MBしかリザーブしない ○ MaxPermSizeはプラットフォームやHotSpot VMの種 類によりデフォルト値が異なります  CompressedClassSpaceのデフォルトは1GB  1GBリザーブしてしまう!! デフォルトのまま使うときは オーバーコミットに注意しましょう!
  43. 43. MaxMetaspaceSize 青天井! OSに殺されるかも…
  44. 44. 古の情報 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クラスはロードできるよ!という話
  45. 45. 1クラスあたりの占有サイズ  フィールド数、メソッド数によって異なります  一概に「だいたいxxバイト」と表現できません 実測一番!
  46. 46. と、いうわけで… -XX:MaxMetaspaceSize=そこそこ -XX:CompressedClassSpaceSize=100m ※責任はもちません -XX:MaxMetaspaceSize=そこそこ ①-Xmx32g以下の場合 ②-Xmx32g超えの場合 ③もう何も気にしたくない場合 -XX:-UseCompressedClassPointers

×