SlideShare a Scribd company logo
Java 8 HotSpot meeting 
JVM内部の基本的な話 
14年10月23日木曜日1
Java 8 HotSpotMeeting 
自己紹介 
COPYRIGHT 2014 PLUGRAM, INC. 
@tan_go238 
PLUGRAM, Inc. 
14年10月23日木曜日2
Java 8 HotSpotMeeting 
もくじ 
・コマンドライン引数 
・OOPとか 
・Object Locking 
・Compressed OOP 
・Java8での変更点 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日3
Java 8 HotSpotMeeting 
COPYRIGHT 2014 PLUGRAM, INC. 
コマンドライン引数 
14年10月23日木曜日4
Java 8 HotSpotMeeting 
コマンドライン引数 
コマンドライン引数は3種類 
standard option 
non-standard options 
developer options 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日5
Java 8 HotSpotMeeting 
コマンドライン引数 
コマンドライン引数は3種類 
standard option 
non-standard options 
developer options 
すべてのJVM実装で利用できる 
リリース間の動作も安定している 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日6
Java 8 HotSpotMeeting 
コマンドライン引数 
コマンドライン引数は3種類 
standard option 
non-standard options 
developer options 
java -client -verbose:gc Hello 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日7
Java 8 HotSpotMeeting 
コマンドライン引数 
コマンドライン引数は3種類 
standard option 
non-standard options 
developer options 
COPYRIGHT 2014 PLUGRAM, INC. 
-X で始まる 
すべてのJVM実装で動くことが保証されていない 
予告なく変更されることがある 
14年10月23日木曜日8
Java 8 HotSpotMeeting 
コマンドライン引数 
コマンドライン引数は3種類 
standard option 
non-standard options 
developer options 
java -Xms512m -Xmx512m Hello 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日9
Java 8 HotSpotMeeting 
コマンドライン引数 
コマンドライン引数は3種類 
standard option 
non-standard options 
developer options 
COPYRIGHT 2014 PLUGRAM, INC. 
-XX で始まる 
正しく動作させるために特定のシステム条件が必要になる場合がある 
システム設定パラメータにアクセスできないと使えない場合がある 
普通は使わない。予告なく変更されることがある 
14年10月23日木曜日10
Java 8 HotSpotMeeting 
コマンドライン引数 
コマンドライン引数は3種類 
standard option 
non-standard options 
developer options 
java -client -Xbatch -XX:+PrintIRWithLIR Hello 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日11
Java 8 HotSpotMeeting 
コマンドライン引数 
% java -client -Xbatch -XX:+PrintIRWithLIR Hello 
Error: VM option 'PrintIRWithLIR' is notproduct and is 
available only in debug version of VM. 
Error: Could not create the Java Virtual Machine. 
Error: A fatal exception has occurred. Program will exit. 
一部のコマンドライン引数を使うには 
デバッグ版のJVMが必要になる 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日12
Java 8 HotSpotMeeting 
OpenJDKをビルドする 
% hg clone http://hg.openjdk.java.net/jdk8/jdk8 jdk8_src 
% cd jdk8_src 
% ./get_source.sh 
% bash ./configure --enable-debug --with-target-bits=64 
% make all 
COPYRIGHT 2014 PLUGRAM, INC. 
たった5行! 
(帰ってからやってね!) 
14年10月23日木曜日13
Java 8 HotSpotMeeting 
OpenJDKをビルドする 
% /usr/local/bin/java -client -Xbatch -XX:+PrintIRWithLIR Hello 
__bci__use__tid____instr____________________________________ 
. 0 0 34 B7 [0, 0] -> B8 sux: B8 
label [label:0x3c03ffc8] 
. 0 0 37 std entry B8 
std_entry 
move [rsi|L] [R177|L] 
move [metadata:0xa1e80068|M] [R178|M] 
move [Base:[R178|M] Disp: 108|I] [R179|I] 
add [R179|I] [int:8|I] [R179|I] 
move [R179|I] [Base:[R178|M] Disp: 108|I] 
move [metadata:0xa1c8a048|M] [R180|M] 
logic_and [R179|I] [int:8184|I] [R179|I] 
cmp [R179|I] [int:0|I] 
branch [EQ] [CounterOverflowStub: 0x3c043ba8] 
label [label:0x3c043bd0] 
branch [AL] [B8] 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日14
Java 8 HotSpotMeeting 
COPYRIGHT 2014 PLUGRAM, INC. 
OOPとか 
14年10月23日木曜日15
Java 8 HotSpotMeeting 
OOP(Ordinary Object Pointer) 
・ヒープ上の全てのJavaオブジェクトはOOPとして表現される 
・OOPはC/C++のポインタ(マシン語)でヒープ内の位置を指す 
・OOPのヘッダーは Mark と Klass の2マシン語(ポインタ※) 
・”Mark”はGC、同期化のための情報をもっている 
・”Klass”はクラスのメタデータへのポインタ 
COPYRIGHT 2014 PLUGRAM, INC. 
※Markはポインタではない(後述) 
14年10月23日木曜日16
Java 8 HotSpotMeeting 
OOP(Ordinary Object Pointer) 
hotspot/src/share/vm/oops/oop.hpp (JDK7) 
class oopDesc { 
friend class VMStructs; 
private: 
volatile markOop _mark; 
union _metadata { 
wideKlassOop _klass; 
narrowOop _compressed_klass; 
} _metadata; 
hotspot/src/share/vm/oops/oopsHierarchy.hpp (JDK7) 
typedef class klassOopDesc* wideKlassOop; 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日17
Java 8 HotSpotMeeting 
oopDesc 
oopDescクラスはGC対象となるオブジェクトの抽象的な基底クラス 
oopDescクラスを継承したクラスのインスタンスがGC対象のオブジェクトになる 
hotspot/src/share/vm/oops/oop.hpp (JDK7) 
// oopDesc is the top baseclass for objects classes. The {name}Desc classes describe 
// the format of Java objects so the fields can be accessed from C++. 
// oopDesc is abstract. 
// (see oopHierarchy for complete oop class hierarchy) 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日18
Java 8 HotSpotMeeting 
oopDesc 
oopDescクラスはGC対象となるオブジェクトの抽象的な基底クラス 
oopDescクラスを継承したクラスのインスタンスがGC対象のオブジェクトになる 
hotspot/src/share/vm/oops/oopsHierarcy.hpp (JDK7) 
typedef class oopDesc* oop; 
typedef class instanceOopDesc* instanceOop; 
typedef class methodOopDesc* methodOop; 
typedef class constMethodOopDesc* constMethodOop; 
typedef class methodDataOopDesc* methodDataOop; 
typedef class arrayOopDesc* arrayOop; 
typedef class objArrayOopDesc* objArrayOop; 
typedef class typeArrayOopDesc* typeArrayOop; 
typedef class constantPoolOopDesc* constantPoolOop; 
typedef class constantPoolCacheOopDesc* constantPoolCacheOop; 
typedef class klassOopDesc* klassOop; 
typedef class markOopDesc* markOop; 
typedef class compiledICHolderOopDesc* compiledICHolderOop; 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日19
Java 8 HotSpotMeeting 
klassOopDesc 
・klassOopDescクラスはJava上のクラスを表す 
・Java上の「java.lang.String」は、VM上では 
 klassOopDescクラスのインスタンス(klassOop)になる 
・全てのオブジェクトは klassOop を持っている 
class oopDesc { 
friend class VMStructs; 
private: 
volatile markOop _mark; 
union _metadata { 
wideKlassOop _klass; 
narrowOop _compressed_klass; 
} _metadata; 
COPYRIGHT 2014 PLUGRAM, INC. 
← oop.hpp (JDK7) 
↓ oopsHierarchy.hpp (JDK7) 
typedef class klassOopDesc* wideKlassOop; 
14年10月23日木曜日20
Java 8 HotSpotMeeting 
klassOop 
klassOopはklassクラスのインスタンスを保持しているただの箱 
hotspot/src/share/vm/oops/klassOop.hpp (JDK7) 
// klassOop object layout: 
// [header ] 
// [klass_field] 
// [KLASS ] 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日21
Java 8 HotSpotMeeting 
Klass 
・Klassクラスはさまざまな型情報の抽象的な基底クラス 
・Klassの子クラスにはoopDescの子クラスと対応するクラスが存在する 
 → XXDescのインスタンスには、XXDescに対応したXXKlassを 
   保持するklassOopが格納される 
COPYRIGHT 2014 PLUGRAM, INC. 
http://www.narihiro.info/g1gc-impl-book/object.html 
14年10月23日木曜日22
Java 8 HotSpotMeeting 
OOPとKlassの関係 
InstanceOop = str klassOop = String klassOop = Class 
InstanceOopDesc 
_klass 
COPYRIGHT 2014 PLUGRAM, INC. 
InstanceOopDesc 
InstanceKlass 
InstanceOopDesc 
InstanceKlassKlass 
_klass 
StringオブジェクトのOOP 
14年10月23日木曜日23
Java 8 HotSpotMeeting 
MarkOopDesc 
MarkOopDescはOOPではなく1ワードのデータ 
MarkOopDescの主な内容 
 ・オブジェクトのハッシュ値 
 ・年齢(世代別GCに利用) 
 ・ロックフラグ 
COPYRIGHT 2014 PLUGRAM, INC. 
同期化やGCに利用する 
14年10月23日木曜日24
Java 8 HotSpotMeeting 
MarkOopDesc 
// 64 bits: 
// -------- 
// unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object) 
// JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object) 
// PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object) 
// size:64 ----------------------------------------------------->| (CMS free block) 
// 
// unused:25 hash:31 -->| cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && normal object) 
// JavaThread*:54 epoch:2 cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && biased object) 
// narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object) 
// unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block) 
hotspot/src/share/vm/oops/markOop.hpp (JDK7) 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日25
Java 8 HotSpotMeeting 
Object Locking 
Biased Locking 基本ロック 
https://wikis.oracle.com/display/HotSpotInternals/Synchronization 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日26
Java 8 HotSpotMeeting 
基本ロック 
COPYRIGHT 2014 PLUGRAM, INC. 
Lock状態への遷移 
1. Interpreter frameにBasicObjectLockを積む 
 → ロックを表現 
2. 元の _mark の内容を _displaced_holderへ退避 
3. _markはBasicLockの位置をCAS命令を使って 
 書込む 
runtime/basicLock.hpp - BasicObjectLock 
interpreter/interpreterRuntime.cpp - InterpreterRuntime::monitorenter 
runtime/synchronizer.cpp - ObjectSynchronizer::fast_enter 
runtime/synchronizer.cpp - ObjectSynchronizer::slow_enter 
14年10月23日木曜日27
Java 8 HotSpotMeeting 
基本ロック 
inflate lockは省略・・・ 
異なる2つのスレッドからアクセスされた場合 
inflation処理が行われる 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日28
Java 8 HotSpotMeeting 
Biased Locking 
・基本ロックでは1回のロックで最低1回のCAS命令を使う 
・Biased Lockingのコンセプト 
  - あるスレッドからロックされたオブジェクトは、 
   同じスレッドからロックされる傾向がある。 
  - オブジェクトの中にスレッド情報を埋め込んで、 
   特定のスレッドに偏っている(biased)ことを示す。 
   それによりそのスレッドからのロックはCAS命令なし 
   で行うことができる。 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日29
Java 8 HotSpotMeeting 
Biased Locking 
1. オブジェクトの生成時は anonymously biased 
2. 最初のスレッドがロックすると、そのスレッドのbiasがかかる(CAS操作が必要) 
3. Biasedのかかったスレッドがロックする場合は _mark に変更が不要 
4. ロックの衝突などが発生するとbiasをかけるのをやめて通常の状態に戻る 
 → 以降、基本ロックを使用する 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日30
Java 8 HotSpotMeeting 
COPYRIGHT 2014 PLUGRAM, INC. 
CompressedOOP 
14年10月23日木曜日31
Java 8 HotSpotMeeting 
Compressed OOP 
・OOPはオブジェクトに対するポインタを表す 
・ポインタのサイズは通常ネイティブマシンと同じサイズになる 
・LP64では 64ビット、ILP32では32ビット 
・ILP32では最大ヒープサイズが約4GBになる 
・64ビットだとメモリ空間が広くなる代わりにオブジェクトの 
 サイズが大きくなる(1.5倍必要になることも) 
 →帯域幅、キャッシュの不足もあり単純に64bitにするのは厳しい 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日32
Java 8 HotSpotMeeting 
Compressed OOP 
・圧縮OOPは32ビットの値で管理ポインタを表す 
・圧縮OOPから参照先のオブジェクトを見つけるには 
 8倍して64ビットベースのアドレスに加算する必要がある 
・圧縮することにより最大約32GBのヒープサイズに対応 
圧縮OOPはJava6u18からデフォルトでオン 
-XX:-UseCompressedOops で切ることができる 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日33
Java 8 HotSpotMeeting 
Compressed OOP 
・JDK7 + No CompressedOop 
Address of SampleClass class is 0x10f03ad00 
Memory layout of SampleClass object at 0x14af3edd8: 
========================================================== 
[0x0000]: 01 da b1 9b 66 00 00 00 00 ad 03 0f 01 00 00 00 
[0x0010]: 14 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 
[0x0020]: 05 00 00 00 00 00 00 00 
========================================================== 
Field Layout of SampleClass: 
========================================================== 
@16 8 SampleBaseClass.s 
@24 8 SampleClass.l 
@32 8 SampleClass.i 
@40 #shallowSizeOfInstance(SampleClass) 
========================================================== 
[mark] ] 8 byte 
[klass pointer ] 8 byte (4 byte for compressed-oops) 
[fields ] values of all fields including fields from super classes 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日34
Java 8 HotSpotMeeting 
Compressed OOP 
・JDK7 + CompressedOop 
Address of SampleClass class is 0x108415f80 
Memory layout of SampleClass object at 0x14556d498: 
========================================================== 
[0x0000]: 01 bc 00 6f 0a 00 00 00 f0 2b 08 21 14 00 00 00 
[0x0010]: 0a 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 
========================================================== 
Field Layout of SampleClass: 
========================================================== 
@12 4 SampleBaseClass.s 
@16 8 SampleClass.l 
@24 8 SampleClass.i 
@32 #shallowSizeOfInstance(SampleClass) 
========================================================== 
[mark] ] 8 byte 
[klass pointer ] 8 byte (4 byte for compressed-oops) 
[fields ] values of all fields including fields from super classes 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日35
Java 8 HotSpotMeeting 
Compressed OOP 
・JDK7 + CompressedOop(その2) 
Address of SampleClass class is 0x600d71640 
Memory layout of SampleClass object at 0x7ac44de48: 
========================================================== 
[0x0000]: 01 d0 f2 5e 1c 00 00 00 59 5c 03 f8 00 00 00 00 
[0x0010]: 14 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 
[0x0020]: 05 00 00 00 00 00 00 00 
========================================================== 
Field Layout of SampleClass: 
========================================================== 
@16 8 SampleBaseClass.l 
@24 8 SampleClass.l 
@32 8 SampleClass.i 
@40 #shallowSizeOfInstance(SampleClass) 
========================================================== 
COPYRIGHT 2014 PLUGRAM, INC. 
-­‐XX:ObjectAlignmentInBytes=8 
http://www.slideshare.net/DawidWeiss/sizeofobject-how-much-memory-objects-take-on-jvms-and-when-this-may-matter 
14年10月23日木曜日36
Java 8 HotSpotMeeting 
Compressed OOP 
・JDK7 + CompressedOop 
% java -Xbootclasspath/a:ocean-of-memories.jar -jar jol-internals.jar SampleClass 
Running 64-bit HotSpot VM. 
Using compressed references with 3-bit shift. 
Objects are 8 bytes aligned. 
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] 
SampleClass object internals: 
OFFSET SIZE TYPE DESCRIPTION VALUE 
0 4 (object header) 01 00 00 00 (0000 0001 0000 0000 0000 0000 0000 0000) 
4 4 (object header) 00 00 00 00 (0000 0000 0000 0000 0000 0000 0000 0000) 
8 4 (object header) 2d ec ed 20 (0010 1101 1110 1100 1110 1101 0010 0000) 
12 2 short SampleBaseClass.s 20 
14 2 (alignment/padding gap) N/A 
16 8 long SampleClass.l 10 
24 4 int SampleClass.i 5 
28 4 (loss due to the next object alignment) 
Instance size: 32 bytes (estimated, add this JAR via -javaagent: to get accurate result) 
Space losses: 2 bytes internal + 4 bytes external = 6 bytes total 
jol (Java Object Layout) 
http://openjdk.java.net/projects/code-tools/jol/ 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日37
Java 8 HotSpotMeeting 
COPYRIGHT 2014 PLUGRAM, INC. 
Java8での変更点 
14年10月23日木曜日38
Java 8 HotSpotMeeting 
Java8での変更点(今回読んでて気づいたところ) 
OpenJDK 7 
class oopDesc { 
friend class VMStructs; 
private: 
volatile markOop _mark; 
union _metadata { 
wideKlassOop _klass; 
narrowOop _compressed_klass; 
} _metadata; 
COPYRIGHT 2014 PLUGRAM, INC. 
OpenJDK 8 
class oopDesc { 
friend class VMStructs; 
private: 
volatile markOop _mark; 
union _metadata { 
Klass* _klass; 
narrowKlass _compressed_klass; 
} _metadata; 
hotspot/src/share/vm/oops/oop.hpp 
14年10月23日木曜日39
Java 8 HotSpotMeeting 
Java8での変更点(今回読んでて気づいたところ) 
OpenJDK 7 
// Klass layout: 
// [header ] klassOop 
// [klass pointer ] klassOop 
// [C++ vtbl ptr ] (contained in Klass_vtbl) 
// [layout_helper ] 
// [super_check_offset ] 
// [secondary_super_cache] 
// [secondary_supers ] 
// [primary_supers 0] 
// [primary_supers 1] 
// [primary_supers 2] 
// ... 
hotspot/src/share/vm/oops/klass.hpp 
COPYRIGHT 2014 PLUGRAM, INC. 
OpenJDK 8 
// Klass layout: 
// [C++ vtbl ptr ] (contained in Metadata) 
// [layout_helper ] 
// [super_check_offset ] 
// [name ] 
// [secondary_super_cache] 
// [secondary_supers ]supertypes 
// [primary_supers 0] 
// [primary_supers 1] 
// [primary_supers 2] 
// ... 
14年10月23日木曜日40
Java 8 HotSpotMeeting 
Java8での変更点(今回読んでて気づいたところ) 
OpenJDK / jdk8u / jdk8u / hotspot 
diff src/share/vm/oops/instanceKlass.hpp @ 3602:da91efe96a93 
6964458: Reimplement class meta-data storage to use native memory 
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, 
rewrite GC walking, rewrite and rename metadata to be C++ classes 
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland 
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin 
<mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com> 
author 
coleenp 
date 
Sat, 01 Sep 2012 13:25:18 -0400 (2012-09-02) 
parents 
04ade88d9712 
children 
4735d2c84362 
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/diff/da91efe96a93/src/share/vm/oops/instanceKlass.hpp 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日41
Java 8 HotSpotMeeting 
Java8での変更点(今回読んでて気づいたところ) 
・Java8でmetaspaceが導入されたことにより 
 klassOopがなくなった 
・oopDescクラスのKlassのポインタが直接 metaspace 内の 
 アドレスを指すのかはよくわかってない 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日42
ありがとうございました! 
14年10月23日木曜日43
Java 8 HotSpotMeeting 
参考 
徹底解剖「G1GC」実装編 
https://github.com/authorNari/g1gc-impl-book/ 
Locking and Synchronization 
http://www.slideshare.net/nminoru_jp/jvm-readingsynchronization 
OpenJDK Wiki 
https://wiki.openjdk.java.net/dashboard.action 
Dangerous Code: How to be Unsafe with Java Classes & Objects in Memory 
http://zeroturnaround.com/rebellabs/dangerous-code-how-to-be-unsafe-with-java-classes-objects-in-memory/ 
COPYRIGHT 2014 PLUGRAM, INC. 
14年10月23日木曜日44

More Related Content

Jvm internal

  • 1. Java 8 HotSpot meeting JVM内部の基本的な話 14年10月23日木曜日1
  • 2. Java 8 HotSpotMeeting 自己紹介 COPYRIGHT 2014 PLUGRAM, INC. @tan_go238 PLUGRAM, Inc. 14年10月23日木曜日2
  • 3. Java 8 HotSpotMeeting もくじ ・コマンドライン引数 ・OOPとか ・Object Locking ・Compressed OOP ・Java8での変更点 COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日3
  • 4. Java 8 HotSpotMeeting COPYRIGHT 2014 PLUGRAM, INC. コマンドライン引数 14年10月23日木曜日4
  • 5. Java 8 HotSpotMeeting コマンドライン引数 コマンドライン引数は3種類 standard option non-standard options developer options COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日5
  • 6. Java 8 HotSpotMeeting コマンドライン引数 コマンドライン引数は3種類 standard option non-standard options developer options すべてのJVM実装で利用できる リリース間の動作も安定している COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日6
  • 7. Java 8 HotSpotMeeting コマンドライン引数 コマンドライン引数は3種類 standard option non-standard options developer options java -client -verbose:gc Hello COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日7
  • 8. Java 8 HotSpotMeeting コマンドライン引数 コマンドライン引数は3種類 standard option non-standard options developer options COPYRIGHT 2014 PLUGRAM, INC. -X で始まる すべてのJVM実装で動くことが保証されていない 予告なく変更されることがある 14年10月23日木曜日8
  • 9. Java 8 HotSpotMeeting コマンドライン引数 コマンドライン引数は3種類 standard option non-standard options developer options java -Xms512m -Xmx512m Hello COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日9
  • 10. Java 8 HotSpotMeeting コマンドライン引数 コマンドライン引数は3種類 standard option non-standard options developer options COPYRIGHT 2014 PLUGRAM, INC. -XX で始まる 正しく動作させるために特定のシステム条件が必要になる場合がある システム設定パラメータにアクセスできないと使えない場合がある 普通は使わない。予告なく変更されることがある 14年10月23日木曜日10
  • 11. Java 8 HotSpotMeeting コマンドライン引数 コマンドライン引数は3種類 standard option non-standard options developer options java -client -Xbatch -XX:+PrintIRWithLIR Hello COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日11
  • 12. Java 8 HotSpotMeeting コマンドライン引数 % java -client -Xbatch -XX:+PrintIRWithLIR Hello Error: VM option 'PrintIRWithLIR' is notproduct and is available only in debug version of VM. Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. 一部のコマンドライン引数を使うには デバッグ版のJVMが必要になる COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日12
  • 13. Java 8 HotSpotMeeting OpenJDKをビルドする % hg clone http://hg.openjdk.java.net/jdk8/jdk8 jdk8_src % cd jdk8_src % ./get_source.sh % bash ./configure --enable-debug --with-target-bits=64 % make all COPYRIGHT 2014 PLUGRAM, INC. たった5行! (帰ってからやってね!) 14年10月23日木曜日13
  • 14. Java 8 HotSpotMeeting OpenJDKをビルドする % /usr/local/bin/java -client -Xbatch -XX:+PrintIRWithLIR Hello __bci__use__tid____instr____________________________________ . 0 0 34 B7 [0, 0] -> B8 sux: B8 label [label:0x3c03ffc8] . 0 0 37 std entry B8 std_entry move [rsi|L] [R177|L] move [metadata:0xa1e80068|M] [R178|M] move [Base:[R178|M] Disp: 108|I] [R179|I] add [R179|I] [int:8|I] [R179|I] move [R179|I] [Base:[R178|M] Disp: 108|I] move [metadata:0xa1c8a048|M] [R180|M] logic_and [R179|I] [int:8184|I] [R179|I] cmp [R179|I] [int:0|I] branch [EQ] [CounterOverflowStub: 0x3c043ba8] label [label:0x3c043bd0] branch [AL] [B8] COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日14
  • 15. Java 8 HotSpotMeeting COPYRIGHT 2014 PLUGRAM, INC. OOPとか 14年10月23日木曜日15
  • 16. Java 8 HotSpotMeeting OOP(Ordinary Object Pointer) ・ヒープ上の全てのJavaオブジェクトはOOPとして表現される ・OOPはC/C++のポインタ(マシン語)でヒープ内の位置を指す ・OOPのヘッダーは Mark と Klass の2マシン語(ポインタ※) ・”Mark”はGC、同期化のための情報をもっている ・”Klass”はクラスのメタデータへのポインタ COPYRIGHT 2014 PLUGRAM, INC. ※Markはポインタではない(後述) 14年10月23日木曜日16
  • 17. Java 8 HotSpotMeeting OOP(Ordinary Object Pointer) hotspot/src/share/vm/oops/oop.hpp (JDK7) class oopDesc { friend class VMStructs; private: volatile markOop _mark; union _metadata { wideKlassOop _klass; narrowOop _compressed_klass; } _metadata; hotspot/src/share/vm/oops/oopsHierarchy.hpp (JDK7) typedef class klassOopDesc* wideKlassOop; COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日17
  • 18. Java 8 HotSpotMeeting oopDesc oopDescクラスはGC対象となるオブジェクトの抽象的な基底クラス oopDescクラスを継承したクラスのインスタンスがGC対象のオブジェクトになる hotspot/src/share/vm/oops/oop.hpp (JDK7) // oopDesc is the top baseclass for objects classes. The {name}Desc classes describe // the format of Java objects so the fields can be accessed from C++. // oopDesc is abstract. // (see oopHierarchy for complete oop class hierarchy) COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日18
  • 19. Java 8 HotSpotMeeting oopDesc oopDescクラスはGC対象となるオブジェクトの抽象的な基底クラス oopDescクラスを継承したクラスのインスタンスがGC対象のオブジェクトになる hotspot/src/share/vm/oops/oopsHierarcy.hpp (JDK7) typedef class oopDesc* oop; typedef class instanceOopDesc* instanceOop; typedef class methodOopDesc* methodOop; typedef class constMethodOopDesc* constMethodOop; typedef class methodDataOopDesc* methodDataOop; typedef class arrayOopDesc* arrayOop; typedef class objArrayOopDesc* objArrayOop; typedef class typeArrayOopDesc* typeArrayOop; typedef class constantPoolOopDesc* constantPoolOop; typedef class constantPoolCacheOopDesc* constantPoolCacheOop; typedef class klassOopDesc* klassOop; typedef class markOopDesc* markOop; typedef class compiledICHolderOopDesc* compiledICHolderOop; COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日19
  • 20. Java 8 HotSpotMeeting klassOopDesc ・klassOopDescクラスはJava上のクラスを表す ・Java上の「java.lang.String」は、VM上では  klassOopDescクラスのインスタンス(klassOop)になる ・全てのオブジェクトは klassOop を持っている class oopDesc { friend class VMStructs; private: volatile markOop _mark; union _metadata { wideKlassOop _klass; narrowOop _compressed_klass; } _metadata; COPYRIGHT 2014 PLUGRAM, INC. ← oop.hpp (JDK7) ↓ oopsHierarchy.hpp (JDK7) typedef class klassOopDesc* wideKlassOop; 14年10月23日木曜日20
  • 21. Java 8 HotSpotMeeting klassOop klassOopはklassクラスのインスタンスを保持しているただの箱 hotspot/src/share/vm/oops/klassOop.hpp (JDK7) // klassOop object layout: // [header ] // [klass_field] // [KLASS ] COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日21
  • 22. Java 8 HotSpotMeeting Klass ・Klassクラスはさまざまな型情報の抽象的な基底クラス ・Klassの子クラスにはoopDescの子クラスと対応するクラスが存在する  → XXDescのインスタンスには、XXDescに対応したXXKlassを    保持するklassOopが格納される COPYRIGHT 2014 PLUGRAM, INC. http://www.narihiro.info/g1gc-impl-book/object.html 14年10月23日木曜日22
  • 23. Java 8 HotSpotMeeting OOPとKlassの関係 InstanceOop = str klassOop = String klassOop = Class InstanceOopDesc _klass COPYRIGHT 2014 PLUGRAM, INC. InstanceOopDesc InstanceKlass InstanceOopDesc InstanceKlassKlass _klass StringオブジェクトのOOP 14年10月23日木曜日23
  • 24. Java 8 HotSpotMeeting MarkOopDesc MarkOopDescはOOPではなく1ワードのデータ MarkOopDescの主な内容  ・オブジェクトのハッシュ値  ・年齢(世代別GCに利用)  ・ロックフラグ COPYRIGHT 2014 PLUGRAM, INC. 同期化やGCに利用する 14年10月23日木曜日24
  • 25. Java 8 HotSpotMeeting MarkOopDesc // 64 bits: // -------- // unused:25 hash:31 -->| unused:1 age:4 biased_lock:1 lock:2 (normal object) // JavaThread*:54 epoch:2 unused:1 age:4 biased_lock:1 lock:2 (biased object) // PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object) // size:64 ----------------------------------------------------->| (CMS free block) // // unused:25 hash:31 -->| cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && normal object) // JavaThread*:54 epoch:2 cms_free:1 age:4 biased_lock:1 lock:2 (COOPs && biased object) // narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object) // unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block) hotspot/src/share/vm/oops/markOop.hpp (JDK7) COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日25
  • 26. Java 8 HotSpotMeeting Object Locking Biased Locking 基本ロック https://wikis.oracle.com/display/HotSpotInternals/Synchronization COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日26
  • 27. Java 8 HotSpotMeeting 基本ロック COPYRIGHT 2014 PLUGRAM, INC. Lock状態への遷移 1. Interpreter frameにBasicObjectLockを積む  → ロックを表現 2. 元の _mark の内容を _displaced_holderへ退避 3. _markはBasicLockの位置をCAS命令を使って  書込む runtime/basicLock.hpp - BasicObjectLock interpreter/interpreterRuntime.cpp - InterpreterRuntime::monitorenter runtime/synchronizer.cpp - ObjectSynchronizer::fast_enter runtime/synchronizer.cpp - ObjectSynchronizer::slow_enter 14年10月23日木曜日27
  • 28. Java 8 HotSpotMeeting 基本ロック inflate lockは省略・・・ 異なる2つのスレッドからアクセスされた場合 inflation処理が行われる COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日28
  • 29. Java 8 HotSpotMeeting Biased Locking ・基本ロックでは1回のロックで最低1回のCAS命令を使う ・Biased Lockingのコンセプト   - あるスレッドからロックされたオブジェクトは、    同じスレッドからロックされる傾向がある。   - オブジェクトの中にスレッド情報を埋め込んで、    特定のスレッドに偏っている(biased)ことを示す。    それによりそのスレッドからのロックはCAS命令なし    で行うことができる。 COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日29
  • 30. Java 8 HotSpotMeeting Biased Locking 1. オブジェクトの生成時は anonymously biased 2. 最初のスレッドがロックすると、そのスレッドのbiasがかかる(CAS操作が必要) 3. Biasedのかかったスレッドがロックする場合は _mark に変更が不要 4. ロックの衝突などが発生するとbiasをかけるのをやめて通常の状態に戻る  → 以降、基本ロックを使用する COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日30
  • 31. Java 8 HotSpotMeeting COPYRIGHT 2014 PLUGRAM, INC. CompressedOOP 14年10月23日木曜日31
  • 32. Java 8 HotSpotMeeting Compressed OOP ・OOPはオブジェクトに対するポインタを表す ・ポインタのサイズは通常ネイティブマシンと同じサイズになる ・LP64では 64ビット、ILP32では32ビット ・ILP32では最大ヒープサイズが約4GBになる ・64ビットだとメモリ空間が広くなる代わりにオブジェクトの  サイズが大きくなる(1.5倍必要になることも)  →帯域幅、キャッシュの不足もあり単純に64bitにするのは厳しい COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日32
  • 33. Java 8 HotSpotMeeting Compressed OOP ・圧縮OOPは32ビットの値で管理ポインタを表す ・圧縮OOPから参照先のオブジェクトを見つけるには  8倍して64ビットベースのアドレスに加算する必要がある ・圧縮することにより最大約32GBのヒープサイズに対応 圧縮OOPはJava6u18からデフォルトでオン -XX:-UseCompressedOops で切ることができる COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日33
  • 34. Java 8 HotSpotMeeting Compressed OOP ・JDK7 + No CompressedOop Address of SampleClass class is 0x10f03ad00 Memory layout of SampleClass object at 0x14af3edd8: ========================================================== [0x0000]: 01 da b1 9b 66 00 00 00 00 ad 03 0f 01 00 00 00 [0x0010]: 14 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 [0x0020]: 05 00 00 00 00 00 00 00 ========================================================== Field Layout of SampleClass: ========================================================== @16 8 SampleBaseClass.s @24 8 SampleClass.l @32 8 SampleClass.i @40 #shallowSizeOfInstance(SampleClass) ========================================================== [mark] ] 8 byte [klass pointer ] 8 byte (4 byte for compressed-oops) [fields ] values of all fields including fields from super classes COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日34
  • 35. Java 8 HotSpotMeeting Compressed OOP ・JDK7 + CompressedOop Address of SampleClass class is 0x108415f80 Memory layout of SampleClass object at 0x14556d498: ========================================================== [0x0000]: 01 bc 00 6f 0a 00 00 00 f0 2b 08 21 14 00 00 00 [0x0010]: 0a 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 ========================================================== Field Layout of SampleClass: ========================================================== @12 4 SampleBaseClass.s @16 8 SampleClass.l @24 8 SampleClass.i @32 #shallowSizeOfInstance(SampleClass) ========================================================== [mark] ] 8 byte [klass pointer ] 8 byte (4 byte for compressed-oops) [fields ] values of all fields including fields from super classes COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日35
  • 36. Java 8 HotSpotMeeting Compressed OOP ・JDK7 + CompressedOop(その2) Address of SampleClass class is 0x600d71640 Memory layout of SampleClass object at 0x7ac44de48: ========================================================== [0x0000]: 01 d0 f2 5e 1c 00 00 00 59 5c 03 f8 00 00 00 00 [0x0010]: 14 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 [0x0020]: 05 00 00 00 00 00 00 00 ========================================================== Field Layout of SampleClass: ========================================================== @16 8 SampleBaseClass.l @24 8 SampleClass.l @32 8 SampleClass.i @40 #shallowSizeOfInstance(SampleClass) ========================================================== COPYRIGHT 2014 PLUGRAM, INC. -­‐XX:ObjectAlignmentInBytes=8 http://www.slideshare.net/DawidWeiss/sizeofobject-how-much-memory-objects-take-on-jvms-and-when-this-may-matter 14年10月23日木曜日36
  • 37. Java 8 HotSpotMeeting Compressed OOP ・JDK7 + CompressedOop % java -Xbootclasspath/a:ocean-of-memories.jar -jar jol-internals.jar SampleClass Running 64-bit HotSpot VM. Using compressed references with 3-bit shift. Objects are 8 bytes aligned. Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes] SampleClass object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 (0000 0001 0000 0000 0000 0000 0000 0000) 4 4 (object header) 00 00 00 00 (0000 0000 0000 0000 0000 0000 0000 0000) 8 4 (object header) 2d ec ed 20 (0010 1101 1110 1100 1110 1101 0010 0000) 12 2 short SampleBaseClass.s 20 14 2 (alignment/padding gap) N/A 16 8 long SampleClass.l 10 24 4 int SampleClass.i 5 28 4 (loss due to the next object alignment) Instance size: 32 bytes (estimated, add this JAR via -javaagent: to get accurate result) Space losses: 2 bytes internal + 4 bytes external = 6 bytes total jol (Java Object Layout) http://openjdk.java.net/projects/code-tools/jol/ COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日37
  • 38. Java 8 HotSpotMeeting COPYRIGHT 2014 PLUGRAM, INC. Java8での変更点 14年10月23日木曜日38
  • 39. Java 8 HotSpotMeeting Java8での変更点(今回読んでて気づいたところ) OpenJDK 7 class oopDesc { friend class VMStructs; private: volatile markOop _mark; union _metadata { wideKlassOop _klass; narrowOop _compressed_klass; } _metadata; COPYRIGHT 2014 PLUGRAM, INC. OpenJDK 8 class oopDesc { friend class VMStructs; private: volatile markOop _mark; union _metadata { Klass* _klass; narrowKlass _compressed_klass; } _metadata; hotspot/src/share/vm/oops/oop.hpp 14年10月23日木曜日39
  • 40. Java 8 HotSpotMeeting Java8での変更点(今回読んでて気づいたところ) OpenJDK 7 // Klass layout: // [header ] klassOop // [klass pointer ] klassOop // [C++ vtbl ptr ] (contained in Klass_vtbl) // [layout_helper ] // [super_check_offset ] // [secondary_super_cache] // [secondary_supers ] // [primary_supers 0] // [primary_supers 1] // [primary_supers 2] // ... hotspot/src/share/vm/oops/klass.hpp COPYRIGHT 2014 PLUGRAM, INC. OpenJDK 8 // Klass layout: // [C++ vtbl ptr ] (contained in Metadata) // [layout_helper ] // [super_check_offset ] // [name ] // [secondary_super_cache] // [secondary_supers ]supertypes // [primary_supers 0] // [primary_supers 1] // [primary_supers 2] // ... 14年10月23日木曜日40
  • 41. Java 8 HotSpotMeeting Java8での変更点(今回読んでて気づいたところ) OpenJDK / jdk8u / jdk8u / hotspot diff src/share/vm/oops/instanceKlass.hpp @ 3602:da91efe96a93 6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <[email protected]>, stefank <[email protected]>, mgerdin <[email protected]>, never <[email protected]> author coleenp date Sat, 01 Sep 2012 13:25:18 -0400 (2012-09-02) parents 04ade88d9712 children 4735d2c84362 http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/diff/da91efe96a93/src/share/vm/oops/instanceKlass.hpp COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日41
  • 42. Java 8 HotSpotMeeting Java8での変更点(今回読んでて気づいたところ) ・Java8でmetaspaceが導入されたことにより  klassOopがなくなった ・oopDescクラスのKlassのポインタが直接 metaspace 内の  アドレスを指すのかはよくわかってない COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日42
  • 44. Java 8 HotSpotMeeting 参考 徹底解剖「G1GC」実装編 https://github.com/authorNari/g1gc-impl-book/ Locking and Synchronization http://www.slideshare.net/nminoru_jp/jvm-readingsynchronization OpenJDK Wiki https://wiki.openjdk.java.net/dashboard.action Dangerous Code: How to be Unsafe with Java Classes & Objects in Memory http://zeroturnaround.com/rebellabs/dangerous-code-how-to-be-unsafe-with-java-classes-objects-in-memory/ COPYRIGHT 2014 PLUGRAM, INC. 14年10月23日木曜日44