Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
JVM in Action
Search
Go Tanaka
July 20, 2017
Programming
730
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
JVM in Action
Go Tanaka
July 20, 2017
More Decks by Go Tanaka
See All by Go Tanaka
TAKT & TeamKit
tan_go238
0
69
なぜAIは チーム開発を 速くしないのか
tan_go238
9
4.5k
事業を理解するために勉強したこと
tan_go238
0
1.5k
RDRAと業務と私
tan_go238
6
5.6k
エンジニアのための情報設計入門
tan_go238
10
8.1k
Ordinary Object Pointer in JVM
tan_go238
5
6.2k
フロントエンドの基礎知識
tan_go238
28
10k
Reactive Microservices Architecture
tan_go238
0
320
たぶん便利なパターンマッチ
tan_go238
0
360
Other Decks in Programming
See All in Programming
気持ちぃ〜角丸 Squircle
ryu1013
0
340
SFCで実現する病院・医療システムの動的組み立て式UI
koukimiura
1
120
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
1.2k
R8 の設定見直しでアプリサイズ削減
andpad
0
230
npm との違いを手がかりにGo の依存管理を理解したい
optim
0
1.1k
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
200
조합이폭발하는디자인시스템이걸눈으로도테스트하라고요
giljongyu
0
590
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
5
840
graphql-ruby を Spinel で速くしようとした話
mtsmfm
0
120
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
460
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
190
クラウドエージェントは、 何がそんなに便利なのか / what makes cloud agents so useful
rkaga
3
550
Featured
See All Featured
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
580
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
450
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
What's in a price? How to price your products and services
michaelherold
247
13k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
310
Writing Fast Ruby
sferik
630
63k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
580
Six Lessons from altMBA
skipperchong
29
4.5k
Transcript
WWW.SITE2MAX.PRO PowerPoint & KeyNote Templates +7.ιʔείʔυೖ @tan_go238
Go Tanaka ओʹ1)1ॻ͍ͯ·͢ +7.ιʔείʔυϦʔσΟϯάझຯ 【運営スタッフ】 関西Javaエンジニアの会 Scala関西 Summit Freelance Engineer
@UBO@HP
ࠂ 4DBMBؔ4VNNJU ݄࣌ ॴఱຬݚमηϯλʔʢ+3େࡕͷྡͷӺͷ͙ۙ͘͢ʣ
͜ͷηογϣϯͰͷ+7.)PU4QPU7.ͷ͜ͱΛࢦ͠·͢ɻ +BWBݴޠ༷+BWBԾϚγϯ༷ʹهࡌ͞Ε͍ͯͳ͍͜ͱ͕ଟ͍Ͱ͢ɻ ΑͬͯɺҰ෦࣮ࡍͷಈ࡞ͱҟͳΔ͜ͱ͕͋Δ͔͠Ε·ͤΜɻ ·ͨझຯͰ+7.Λௐ͍ͯΔͨΊҰ෦ޡΓ͕͋Δ͔͠Ε·ͤΜ͕ ͦͷͱ͖͝ࢦఠ͍ͩ͘͞ɻ ҙ
+7.ͷιʔείʔυΛͯ͢ཧղ͢Δͷ͍͠Ͱ͕͢ ༻ޠΛ͓͑ͯ͞ͻͱͭͻͱͭಈ࡞Λཧղ͍ͯ͘͠ͱ ιʔείʔυࣗମ៉ྷʹॻ͔Εͯ͋Γʢͳ͔ʹμʔςΟϋοΫ͋Δʣ ·ͨιʔείʔυதͷίϝϯτυΩϡϝϯτॆ࣮͍ͯ͠ΔͷͰ ҙ֎ͱ؆୯ʹಡΊΔΑ͏ʹͳΕ·͢ʢଟগͷؾ߹͍ͱࠜੑ͕ඞཁʣ ͜ͷηογϣϯͰҰ൪࠷ॳͷͱ͔͔ͬΓ෦ʹ͍ͭͯͤͨΒͱࢥͬͯͨͷͰ͕͢ ్தɺΨοπϦ͍ͬͯ͠·ͬͨͷͰԿͱͳ͘ฉ͖ྲྀͯ͠Β͑Εͱࢥ͍·͢ ͡Ίʹ
࣭ 0QFO+%,ͷίϛολͷਓ͍·͔͢ʁ +7.ͷτϥϒϧγϡʔςΟϯά͕ࣄͷਓ͍·͔͢ʁ
0QFO+%,ͷίϛολͷਓ͍·͔͢ʁ +7.ͷτϥϒϧγϡʔςΟϯά͕ࣄͷਓ͍·͔͢ʁ :FTɿͬͯΔ༰ͳͷͰɺಛʹ͜ͷηογϣϯฉ͘ඞཁͳ͍Ͱ͢ /PɿͬͯͯΘͳ͍ͷͰɺಛʹ͜ͷηογϣϯฉ͘ඞཁͳ͍Ͱ͢ ࣭
࣍
༻ޠΛ͓͑͞Α͏ 001·ΘΓ ϝϞϦϨΠΞτ +7.ͷىಈ ࣍
༻ޠΛ͓͑͞Α͏ )PU4QPU(MPTTBSZPG5FSNT )PU4QPUͰΑ͘ΘΕΔ༻ޠʹ͍ͭͯղઆ͞Ε͍ͯΔ BEBQUJWFTQJOOJOHCJBTFEMPDLJOHCMPDLTUBSUUBCMFCPPUTUSBQDMBTTMPBEFSCZUFDPEFWFSJpDBUJPO $$PNQJMFS$$PNQJMFSDBSEUBCMFDMBTTEBUBTIBSJOHDMBTTIJFSBDIZBOBMZTJTDPEFDBDIF DPNQBDUJPODPODVSSFODZDPODVSSFOUHBSCBHFDPMMFDUJPODPQZJOHHBSCBHFDPMMFDUJPOEFPQUJNJ[BUJPO EFQFOEFODZFEFOGSFFMJTUHBSCBHFDPMMFDUJPOHBSCBHFDPMMFDUJPOSPPU($NBQHFOFSBUJPOBMHBSCBHF DPMMFDUJPOIBOEMFIPUMPDLJOUFSQSFUFS+*5DPNQJMFST+/*+7.5*LMBTTQPJOUFSNBSLXPSEONFUIPE PCKFDUIFBEFSPCKFDUQSPNPUJPOPMEHFOFSBUJPOPOTUBDLSFQMBDFNFOUPPQQBSBMMFMDMBTTMPBEJOHQBSBMMFM HBSCBHFDPMMFDUJPOQFSNBOFOUHFOFSBUJPOSFNFNCFSFETFUTBGFQPJOUTFBPGOPEFT
4FSWJDFBCJMJUZ"HFOU 4" TUBDLNBQ4UBDL.BQ5BCMFTVSWJWPSTQBDFTZODISPOJ[BUJPO5-"# VODPNNPOUSBQWFSJpFS7.0QFSBUJPOTXSJUFCBSSJFSZPVOHHFOFSBUJPO http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html
༻ޠΛ͓͑͞Α͏ ͜ΕΒͷ༻ޠ֮ͯ͑͢Δඞཁͳ͍ ग़͖ͯͨͱ͖ʹௐΕ͍͍ ίʔυதʹઆ໌͕ॻ͍ͯ͋Δ߹͕ଟ͍
༻ޠΛ͓͑͞Α͏ )PU4QPU(MPTTBSZPG5FSNT )PU4QPUͰΑ͘ΘΕΔ༻ޠʹ͍ͭͯղઆ͞Ε͍ͯΔ BEBQUJWFTQJOOJOHCJBTFEMPDLJOHCMPDLTUBSUUBCMFCPPUTUSBQDMBTTMPBEFSCZUFDPEFWFSJpDBUJPO $$PNQJMFS$$PNQJMFSDBSEUBCMFDMBTTEBUBTIBSJOHDMBTTIJFSBDIZBOBMZTJTDPEFDBDIF DPNQBDUJPODPODVSSFODZDPODVSSFOUHBSCBHFDPMMFDUJPODPQZJOHHBSCBHFDPMMFDUJPOEFPQUJNJ[BUJPO EFQFOEFODZFEFOGSFFMJTUHBSCBHFDPMMFDUJPOHBSCBHFDPMMFDUJPOSPPU($NBQHFOFSBUJPOBMHBSCBHF DPMMFDUJPOIBOEMFIPUMPDLJOUFSQSFUFS+*5DPNQJMFST+/*+7.5*LMBTTQPJOUFSNBSLXPSEONFUIPE PCKFDUIFBEFSPCKFDUQSPNPUJPOPMEHFOFSBUJPOPOTUBDLSFQMBDFNFOUPPQQBSBMMFMDMBTTMPBEJOHQBSBMMFM HBSCBHFDPMMFDUJPOQFSNBOFOUHFOFSBUJPOSFNFNCFSFETFUTBGFQPJOUTFBPGOPEFT
4FSWJDFBCJMJUZ"HFOU 4" TUBDLNBQ4UBDL.BQ5BCMFTVSWJWPSTQBDFTZODISPOJ[BUJPO5-"# VODPNNPOUSBQWFSJpFS7.0QFSBUJPOTXSJUFCBSSJFSZPVOHHFOFSBUJPO http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html
༻ޠΛ͓͑͞Α͏ )PU4QPU(MPTTBSZPG5FSNT BEBQUJWFTQJOOJOHCJBTFEMPDLJOHCMPDLTUBSUUBCMFCPPUTUSBQDMBTTMPBEFSCZUFDPEFWFSJpDBUJPO $$PNQJMFS$$PNQJMFSDBSEUBCMFDMBTTEBUBTIBSJOHDMBTTIJFSBDIZBOBMZTJTDPEFDBDIF DPNQBDUJPODPODVSSFODZDPODVSSFOUHBSCBHFDPMMFDUJPODPQZJOHHBSCBHFDPMMFDUJPOEFPQUJNJ[BUJPO EFQFOEFODZFEFOGSFFMJTUHBSCBHFDPMMFDUJPOHBSCBHFDPMMFDUJPOSPPU($NBQHFOFSBUJPOBMHBSCBHF DPMMFDUJPOIBOEMFIPUMPDLJOUFSQSFUFS+*5DPNQJMFST+/*+7.5*LMBTTQPJOUFSNBSLXPSEONFUIPE PCKFDUIFBEFSPCKFDUQSPNPUJPOPMEHFOFSBUJPOPOTUBDLSFQMBDFNFOUPPQQBSBMMFMDMBTTMPBEJOHQBSBMMFM HBSCBHFDPMMFDUJPOQFSNBOFOUHFOFSBUJPOSFNFNCFSFETFUTBGFQPJOUTFBPGOPEFT 4FSWJDFBCJMJUZ"HFOU
4" TUBDLNBQ4UBDL.BQ5BCMFTVSWJWPSTQBDFTZODISPOJ[BUJPO5-"# VODPNNPOUSBQWFSJpFS7.0QFSBUJPOTXSJUFCBSSJFSZPVOHHFOFSBUJPO http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html )PU4QPUͰΑ͘ΘΕΔ༻ޠʹ͍ͭͯղઆ͞Ε͍ͯΔ
༻ޠΛ͓͑͞Α͏ 001 0SEJOBSZ0CKFDU1PJOUFS +BWBΦϒδΣΫτ001ͱͯ͠දݱ͞Εɺώʔϓ্ʹ͋Δ 001$$ ͷϙΠϯλͰώʔϓͷҐஔΛࢦ͢
༻ޠΛ͓͑͞Α͏ PCKFDUIFBEFS ($͕ཧ͢Δͯ͢ͷώʔϓΦϒδΣΫτ 001 ͷઌ಄ͷڞ௨ߏ ώʔϓΦϒδΣΫτͷϨΠΞτλΠϓɺ($ঢ়ଶɺಉظঢ়ଶɺ ҰҙʹͳΔϋογϡίʔυʹؔ͢Δجຊతͳใؚ͕·Ε͍ͯΔ ͭͷϫʔυͰߏ͞Ε͍ͯΔʢ.BSL ,MBTTʣ ྻͷޙʹ͞ϑΟʔϧυ͕ଓ͘
༻ޠΛ͓͑͞Α͏ NBSLXPSE ͯ͢ͷPCKFDUIFBEFSͷ࠷ॳͷϫʔυ ௨ৗɺಉظঢ়ଶͱࣝผϋογϡίʔυΛؚΉϏοτϑΟʔϧυͷηοτ ಉظؔ࿈ใͷϙΠϯλͰ͋Δ ($ͷؒɺ($ঢ়ଶϏοτΛؚΉ͜ͱ͕Ͱ͖Δɻ
༻ޠΛ͓͑͞Α͏ LMBTTQPJOUFS ͯ͢ͷPCKFDUIFBEFSͷ̎൪ͷϫʔυ ݩͷΦϒδΣΫτͷϨΠΞτͱಈ࡞Λهड़͢ΔผͷϝλΦϒδΣΫτΛࢦ͢ +BWBΦϒδΣΫτͷ߹ɺLMBTTʹ$ ελΠϧͷlWUBCMFؚ͕·Ε͍ͯΔ
͓͞Β͍ PPQ +BWBͷΦϒδΣΫτΛද͢ɻ$$ ͷϙΠϯλͰώʔϓͷҐஔΛࢦ͢ PCKFDUIFBEFS ($͕ཧ͢Δͯ͢ͷώʔϓΦϒδΣΫτ 001 ͷઌ಄ͷڞ௨ߏ NBSLXPSE ͯ͢ͷPCKFDUIFBEFSͷ࠷ॳͷϫʔυɻಉظ($ͷใΛ࣋ͭ
LMBTTQPJOUFS ͯ͢ͷPCKFDUIFBEFSͷ̎൪ͷϫʔυɻ+BWBΦϒδΣΫτͷ߹lWUBCMFzؚ͕·ΕΔ
001 _mark _klass Fields 32-bit cpu 64-bit cpu 4 byte
8 byte 4 byte 8 byte -XX:ObjectAlignmentInBytes=8 ͯ͢ͷΦϒδΣΫτόΠτڥքʹஔ͞ΕΔ PCKFDUIFBEFS NBSLXPSE LMBTTQPJOUFS
java.lang.Object object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 16
(object header) N/A Instance size: 16 bytes Space losses: 0 bytes internal + 0 bytes external = 0 bytes total +0-Ͱग़ྗͯ͠Έͨ݁Ռ new Object() すると、64-bit cpu では 16 byte 消費することになる 001
PPQ%FTD JOTUBODF0PQ%FTDʜ+BWBΦϒδΣΫτͷ001 BSSBZ0PQ%FTDʜྻΛද͢001ͷ PCK"SSBZ0PQ%FTDʜྻΦϒδΣΫτͷ001 UZQF"SSBZ0PQ%FTDʜϓϦϛςΟϒͷྻͷ001
$PNQSFTTFE001 CJUϚγϯͰΦϒδΣΫτͷΞυϨεΛѹॖ͢Δ +BWBώʔϓͷ༻ྔΛઅ ώʔϓͷϕʔεΞυϨε͔ΒͷΦϑηοτΛར༻ ѹॖ001+BWBV͔ΒσϑΥϧτͰΦϯ 996TF$PNQSFTTFE0PQTͰΔ͜ͱ͕Ͱ͖Δ http://www.oracle.com/technetwork/jp/articles/java/compressedoops-427542-ja.html ৄ͘͠ KBWB99 1SJOU'MBHT'JOBM)FMMPcHSFQ6TF$PNQSFTTFE0PQTʜ֬ೝ
KBWB99 6OMPDL%JBHOPTUJD7.0QUJPOT99 1SJOU$PNQSFTTFE0PQT.PEF)FMMPʜৄࡉใग़ྗ
,MBTT 001ͷϔομͷҰ෦ ,MBTTΫϥεͷ.FUBTQBDFͷཧϙΠϯλΛද͢ CJUϚγϯͰCZUFɺCJUϚγϯͰCZUF༻͢ΔʢѹॖͰ͖Δʣ http://otndnld.oracle.co.jp/ondemand/javaday2014/pdf/C2-JavaDay-304328.pdf
,MBTTϙΠϯλͷѹॖ $PNQSFTTFE001ͱಉ͡Α͏ʹ+BWB)FBQΛઅ $PNQSFTTFE$MBTT1PJOUFS4QBDF $$14 ͱ͍͏ϝϞϦΤϦΞΛ༻ҙ *OTUBODF,MBTT "SSBZ,MBTT W5BCMFͳͲύϑΥʔϚϯεʹӨڹ͢ΔΫϥε ͷΈ֨ೲ͠ɺͦΕҎ֎.FUBTQBDFʹ֨ೲʢϝιουɺίϯελϯτϓʔϧͳͲʣ
,MBTT ,MBTT͞·͟·ͳܕใͷநతͳجఈΫϥε
*OTUBODF,MBTTʜܕΫϥεͷΠϯελϯε *OTUBODF.JSSPS,MBTTʜKBWBMBOH$MBTTΛද͢ *OTUBODF$MBTT-PBEFS,MBTTʜ*OTUBODF,MBTTͷΫϥεϩʔμ༻ *OTUBODF3FG,MBTTʜKBWBMBOHSFG3FGFSFODFͷαϒΫϥε ɹɹɹɹɹɹɹɹɹɹ TPGUXFBLpOBMQIBOUPN ,MBTT
"SSBZ,MBTTʜྻΛද͢Ϋϥε 0CK"SSBZ,MBTTʜΦϒδΣΫτͷྻͷΫϥε 5ZQF"SSBZ,MBTTʜϓϦϛςΟϒͷྻͷΫϥε ,MBTT
001ͱ,MBTTͷؔ InstanceOop _klass InstanceKlass InstanceKlass _super *OTUBODF0PQTUS ,MBTT4USJOH ,MBTT0CKFDU Metaspace
InstanceOop PPQ$MBTT4USJOH _java_mirror Java Heap String str = “hoge”; InstanceMirrorKlass _klass
.BSL ($ɺಉظԽͷͨΊͷใΛ͍ͬͯΔ CJUϚγϯͰόΠτɺCJUϚγϯͰόΠτͷ͞ʹͳΔ .BSLϙΠϯλͰͳ͘σʔλߏ
.BSL hash age CJU CJU unused:25 hash:31 -->| unused:1 age:4
biased_lock:1 lock:2 (normal object) hash:25 ------------>| age:4 biased_lock:1 lock:2 (normal object) src/share/vm/oops/markOop.hpp ʢྫʣ6OMPDLFE ޙड़ ͷ.BSLͷϝϞϦߏ hash age
.BSL .BSLͷঢ়ଶओʹҎԼͷ̑ͭ ɹ#JBTFE ɹ6OMPDLFE લड़ͷOPSNBMPCKFDU ɹ-JHIUXFJHIU-PDLFE ɹ)FBWZXFJHIU-PDLFE ɹ.BSLFEʢ($ͷΈʣ https://wiki.openjdk.java.net/display/HotSpot/Synchronization
Mark には5種類のデータ構造がある
#JBTFE-PDLJOH جຊϩοΫͰճͷϩοΫͰ࠷ճͷ$"4໋ྩΛ͏ #JBTFE-PDLJOHͷίϯηϓτ ɹɾ͋ΔεϨου͔ΒϩοΫ͞ΕͨΦϒδΣΫτ ɹɹಉ͡εϨου͔ΒϩοΫ͞ΕΔ͕͋Δ ɹɾΦϒδΣΫτͷதʹεϨουใΛຒΊࠐΜͰಛఆͷεϨουʹ ภ͍ͬͯΔ CJBTFE ͜ͱΛࣔ͢ɻͦΕʹΑΓͦͷεϨου͔Βͷ ϩοΫ$"4໋ྩͳ͠Ͱߦ͏͜ͱ͕Ͱ͖Δ
.BSLͷঢ়ଶ#JBTFE ΦϒδΣΫτׂ͕ΓͯΒΕΔ #JBTFE-PDLJOH+BWB͔ΒσϑΥϧτͳͷͰCJBTBCMFPCKFDUʹͳΔ ϩοΫ͢ΔͱUISFBE*%͕ઃఆ͞ΕΔ CJBTFEPCKFDU
SFCJBT͢ΔͱCJBTBCMFPCKFDUʹΔ ҰఆपظͰSFCJBT͢ΔΒ͍͠ ଞͷεϨουͰར༻͞ΕΔͱجຊϩοΫʹͳΔ #JBTFE-PDLJOH͕ղআ͞ΕΔ 0 epoch age 1 01 thread ID epoch age 1 01 JOJUJBMMPDL SFCJBT CJBTBCMFPCKFDU CJBTFEPCKFDU
.BSLͷঢ়ଶ hash code age 0 01 pointer to lock record
00 #JBTFE-PDLJOH͕ར༻Ͱ͖ͳ͍߹جຊϩοΫͷϓϩηεʹͳΔ جຊϩοΫͰϩοΫ͢Δͱ5IJO-PDL͕͔͔Δ εϨου͕͢ͰʹͦͷΦϒδΣΫτͷϩοΫΛ͍࣋ͬͯΔ߹3FDVSTJWF-PDLʹͳΔ ฒߦॲཧͳͲͰෳͷҟͳΔεϨου͔Βಉ͡ΦϒδΣΫτʹରͯ͠ ಉ࣌ʹಉظॲཧ͕ߦΘΕΔͱ*OqBUF-PDLʹͳΔ pointer to heavyweight monitor 10 6OMPDLFE -JHIUXFJHIU-PDLFE )FBWZXFJHIU-PDLFE 5IJO-PDL *OqBUF-PDL ʜVOMPDLFE ʜMPDLFE ʜNPOJUPS
·ͱΊ ͜ΕΒͷ༻ޠ֮ͯ͑͢Δඞཁͳ͍ ग़͖ͯͨͱ͖ʹௐΕ͍͍ ࠓग़͖ͯͨ୯ޠৗۀͰ༻͠·ͤΜ
ϝϞϦϨΠΞτ
ϝϞϦϨΠΞτ _mark _klass Fields 32-bit cpu 64-bit cpu 4 byte
8 byte 4 byte 8 byte -XX:ObjectAlignmentInBytes=8 ͯ͢ͷΦϒδΣΫτόΠτڥքʹஔ͞ΕΔ PCKFDUIFBEFS NBSLXPSE LMBTTQPJOUFS
java.lang.Object object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 16
(object header) N/A Instance size: 16 bytes Space losses: 0 bytes internal + 0 bytes external = 0 bytes total ѹॖ001ͳ͠ java.lang.Object object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 12 (object header) N/A 12 4 (loss due to the next object alignment) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total ѹॖ001͋Γ ϝϞϦϨΠΞτ
001ϔομͷޙʹΫϥεϑΟʔϧυ͕ଓ͘ ϝϞϦઅͷͨΊʹ+7.ఆٛ͞Εͨॱ൪Ͱͳ͘ฒͼସ͑Λߦ͏ ϑΟʔϧυجຊతʹ࣍ͷ༏ઌॱҐͰϝϞϦʹߏ͢Δ 1 double, long 8 2 int, float
4 3 short, char 2 4 boolean, byte 1 5 ΦϒδΣΫτࢀর 8 (64bit) ϝϞϦϨΠΞτ
class A { byte a; int c; short d; long
e; Object f; } ᶃ ᶄ ᶆ ᶅ ᶇ jol.samples.A object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 16 (object header) N/A 16 8 long D.e N/A 24 4 int D.c N/A 28 2 short D.d N/A 30 1 byte D.a N/A 31 1 (alignment/padding gap) 32 8 java.lang.Object D.f N/A Instance size: 40 bytes Space losses: 1 bytes internal + 0 bytes external = 1 bytes total ᶃ ᶄ ᶅ ᶆ ᶇ ѹॖ001ͳ͠ ϝϞϦϨΠΞτ
class A { byte a; int c; short d; long
e; Object f; } ᶃ ᶄ ᶆ ᶅ ᶇ jol.samples.A object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 12 (object header) N/A 12 4 int D.c N/A 16 8 long D.e N/A 24 2 short D.d N/A 26 1 byte D.a N/A 27 1 (alignment/padding gap) 28 4 java.lang.Object D.f N/A Instance size: 32 bytes Space losses: 1 bytes internal + 0 bytes external = 1 bytes total ᶃ ᶄ ᶅ ᶆ ᶇ ѹॖ001͋Γ ϝϞϦϨΠΞτ
αϒΫϥεͷϝϞϦϨΠΞτ ɹ֊͕ҟͳΔΫϥεͷϑΟʔϧυࠞ߹͠ͳ͍ ɹΫϥεͷϑΟʔϧυ͕ઌʹ͖ͯɺαϒΫϥεͷϑΟʔϧυ͕ͦͷޙʹ͘Δ ϝϞϦϨΠΞτ
class A { byte a; } class B extends A
{ long b; short c; byte d; } jol.samples.B object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 12 (object header) N/A 12 1 byte A.a N/A 13 3 (alignment/padding gap) 16 8 long B.b N/A 24 2 short B.c N/A 26 1 byte B.d N/A 27 5 (loss due to the next object alignment) Instance size: 32 bytes Space losses: 3 bytes internal + 5 bytes external = 8 bytes total ϝϞϦϨΠΞτ
String str = “Hello World”; ͜ͷ+BWBΦϒδΣΫτԿCZUFͷϝϞϦΛফඅ͢Δ͔ ϝϞϦϨΠΞτ
+0-Ͱ$MBTT-BZPVUΛΈͯΈΔ String str = “Hello World”; System.out.println(ClassLayout.parseInstance(str).toPrintable()); ϝϞϦϨΠΞτ
+0-Ͱ$MBTT-BZPVUΛΈͯΈΔ java.lang.String object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0
4 (object header) 01 00 00 00 4 4 (object header) 00 00 00 00 8 4 (object header) da 02 00 f8 12 4 char[] String.value [H, e, l, l, o, , W, o, r, l, d] 16 4 int String.hash 0 20 4 (loss due to the next object alignment) Instance size: 24 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total ϝϞϦϨΠΞτ
String str = “Hello World”; System.out.println(GraphLayout.parseInstance(str).toPrintable()); +0-ͰΠϯελϯεͷ(SBQI-BZPVUΛΈͯΈΔ ϝϞϦϨΠΞτ
+0-ͰΠϯελϯεͷ(SBQI-BZPVUΛΈͯΈΔ java.lang.String@532760d8d object externals: ADDRESS SIZE TYPE PATH VALUE 76b98fb58
24 java.lang.String (object) 76b98fb70 40 [C .value [H, e, l, l, o, , W, o, r, l, d] DIBSͷྻͰCZUFফඅ͍ͯ͠Δ ϝϞϦϨΠΞτ
[C object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4
(object header) 01 00 00 00 4 4 (object header) 00 00 00 00 8 4 (object header) 41 00 00 f8 12 4 (object header) 0b 00 00 00 16 22 char [C.<elements> N/A 38 2 (loss due to the next object alignment) Instance size: 40 bytes Space losses: 0 bytes internal + 2 bytes external = 2 bytes total ͜ͷDIBSͷྻͷ$MBTT-BZPVUΛΈͯΈΔ <) F M M P 8 P S M E>ཁૉYC ྻͷ͕͞ϔομʹઃఆ͞ΕΔ ϝϞϦϨΠΞτ
String str = “Hello World”; ͜ͷ+BWBΦϒδΣΫτԿCZUFͷϝϞϦΛফඅ͢Δ͔ 4USJOHCZUF DIBS<>CZUF ߹ܭɿCZUF ϝϞϦϨΠΞτ
_mark _klass char[] String.value int String.hash padding _mark _klass length char [C.<elements> padding CZUF CZUF 4USJOH DIBS<>
+7.ͷιʔείʔυ
+7.ͷιʔείʔυ ιʔείʔυͷϦϙδτϦʢ.FSDVSJBMʣ http://hg.openjdk.java.net/ KEL KEL KELV KEL KELV KEL KEL
+7.ͷιʔείʔυ IPUTQPU IPUTQPUຊମ MJCKWN Λ࡞ΔͨΊͷ.BLFpMFͱιʔείʔυΛೲΊͨσΟϨΫτϦ KEL MJCKWNҎ֎ͷϥΠϒϥϦΛ࡞ΔͨΊͷϑΝΠϧ .BLFpMF ιʔείʔυ ٴͼ+BWB
ͷඪ४ϥΠϒϥϦ༻ͷιʔείʔυ KBWBϑΝΠϧ ΛೲΊͨσΟϨΫτϦ MBOHUPPMT MBOHVBHFUPPMT KBWBD KBWBEPD KBWBI KBWBQ BQU Λ࡞ΔͨΊͷ.BLFpMFͱιʔ είʔυΛೲΊͨσΟϨΫτϦ http://hsmemo.github.io/articles/noazh2rR49.html ˞ଞʹͨ͘͞Μ͋Δ
+7.ͷιʔείʔυ PPQT +BWBͷΦϒδΣΫτཧ +BWBΦϒδΣΫτͷ෦දݱ ʹؔ͢Διʔείʔυ SVOUJNF )PU4QPUͷϥϯλΠϜػೳʹؔ͢Διʔείʔυ NFNPSZ +BWBώʔϓཧʹؔ͢Διʔείʔυ DMBTTpMF
ΫϥεϑΝΠϧཧ ΫϥεϩʔσΟϯάॲཧؚΉ ʹؔ͢Διʔείʔυ JOUFSQSFUFS ΠϯλʔϓϦλؔ࿈ͷιʔείʔυ QSJNT +/*+7.5* TVONJTDVOTBGFʹؔ͢Διʔείʔυ http://hsmemo.github.io/articles/nopoim3uPN.html IPUTQPUTSDTIBSFWNҎԼ ˞ଞʹͨ͘͞Μ͋Δ
+7.ͷىಈ
+7.ͷىಈ )PU4QPU3VOUJNF0WFSWJFX http://openjdk.java.net/groups/hotspot/docs/RuntimeOverview.html ىಈ࣌ͷৄ͍͠ॲཧ͜͜ʹॻ͍ͯ͋Δ http://tango238.github.io/jvm/hotspot-runtime-overview_translated.html ʢҰ෦͚ͩҎલ༁͍ͯ͠Δʣ
+7.ͷىಈ ίϚϯυϥΠϯҾΛղੳ͢ΔɻͦͷଞͷҾ7.ʹ͞ΕΔ ώʔϓαΠζ͓ΑͼελοΫαΠζΛઃఆ͢Δ +7.λΠϓ͓ΑͼڥมΛઃఆ͢Δ
.BJOΫϥεΛಡΈࠐΉ ৽͘͠࡞͞ΕͨεϨουͰ7.Λ࡞͢Δ 7.͕ॳظԽ͞Εɺ.BJO$MBTT͔ΒϝΠϯϝιουͷଐੑΛऔಘ͢Δ ϝΠϯϝιουΛݺͼग़͢ ϝΠϯϝιου࣮ߦྃޙɺൃੜͨ͠ྫ֎ΛνΣοΫɺFYJUεςʔλεΛฦ٫ ϝΠϯεϨουΛσλονɻσλον͢ΔͱεϨουΧϯτΛσΫϦϝϯτ͢Δ ɹɹ͜ΕʹΑΓ%FTUSPZ+BWB7.Λ҆શʹݺͼग़͢͜ͱ͕Ͱ͖Δ +/*@$SFBUF+BWB7. IPUTQPUTSDTIBSFWNQSJNFTKOJDQQ ͋ͨΓ͕ಛʹॏཁ
+7.ͷىಈ ίϚϯυϥΠϯҾΛղੳ͢ΔɻͦͷଞͷҾ7.ʹ͞ΕΔ ώʔϓαΠζ͓ΑͼελοΫαΠζΛઃఆ͢Δ +7.λΠϓ͓ΑͼڥมΛઃఆ͢Δ
.BJOΫϥεΛಡΈࠐΉ ৽͘͠࡞͞ΕͨεϨουͰ7.Λ࡞͢Δ 7.͕ॳظԽ͞Εɺ.BJO$MBTT͔ΒϝΠϯϝιουͷଐੑΛऔಘ͢Δ ϝΠϯϝιουΛݺͼग़͢ ϝΠϯϝιου࣮ߦྃޙɺൃੜͨ͠ྫ֎ΛνΣοΫɺFYJUεςʔλεΛฦ٫ ϝΠϯεϨουΛσλονɻσλον͢ΔͱεϨουΧϯτΛσΫϦϝϯτ͢Δ ɹɹ͜ΕʹΑΓ%FTUSPZ+BWB7.Λ҆શʹݺͼग़͢͜ͱ͕Ͱ͖Δ +/*@$SFBUF+BWB7. IPUTQPUTSDTIBSFWNQSJNFTKOJDQQ ͋ͨΓ͕ಛʹॏཁ ͜ͷΜ·Ͱʢ؆ུԽͨ͠ʣιʔείʔυΛͬͯΈ͍ͨͱࢥ͍·͢
+7.ͷىಈ ΤϯτϦϙΠϯτʢKELVEFWʣ http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/3462d04401ba/src/share/bin/main.c int main(int argc, char **argv) { int
margc; char** margv; const jboolean const_javaw = JNI_FALSE; margc = argc; margv = argv; return JLI_Launch(margc, margv, sizeof(const_jargs) / sizeof(char *), const_jargs, sizeof(const_appclasspath) / sizeof(char *), const_appclasspath, FULL_VERSION, DOT_VERSION, (const_progname != NULL) ? const_progname : *margv, (const_launcher != NULL) ? const_launcher : *margv, (const_jargs != NULL) ? JNI_TRUE : JNI_FALSE, const_cpwildcard, const_javaw, const_ergo_class); }
+7.ͷىಈ ίϚϯυϥΠϯҾΛղੳ͢ΔɻͦͷଞͷҾ7.ʹ͞ΕΔ http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e74259b3eadc/src/share/bin/java.c int JLI_Launch(…) { InitLauncher(javaw); // 初期化 SelectVersion(argc,
argv, &main_class); // JREバージョンの選択 CreateExecutionEnvironment(…); // JVMタイプおよび環境変数を設定 // JVMをロード。ifn->CreateJavaVM = JNI_CreateJavaVM が設定される if (!LoadJavaVM(jvmpath, &ifn)) { return(6); } // コマンドライン引数を解析 if (!ParseArguments(&argc, &argv, &mode, &what, &ret, jrepath)) { return(ret); } SetJavaCommandLineProp(what, argc, argv); SetJavaLauncherProp(); SetJavaLauncherPlatformProps(); return JVMInit(&ifn, threadStackSize, argc, argv, mode, what, ret); }
+7.ͷىಈ ώʔϓαΠζ͓ΑͼελοΫαΠζΛઃఆ͢Δ http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e74259b3eadc/src/share/bin/java.c void AddOption(char *str, void *info) { //
ParseArguments() から実行 if (JLI_StrCCmp(str, "-Xss") == 0) { jlong tmp; if (parse_size(str + 4, &tmp)) { threadStackSize = tmp; } } if (JLI_StrCCmp(str, "-Xmx") == 0) { jlong tmp; if (parse_size(str + 4, &tmp)) { maxHeapSize = tmp; } } if (JLI_StrCCmp(str, "-Xms") == 0) { jlong tmp; if (parse_size(str + 4, &tmp)) { initialHeapSize = tmp; } } }
+7.ͷىಈ +7.λΠϓ͓Αͼڥมʢ-%@-*#3"3:@1"5)ʣΛઃఆ͢Δ http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e74259b3eadc/src/solaris/bin/java_md_solinux.c void CreateExecutionEnvironment(...) { SetExecname(*pargv); // 実行ファイル名を設定 if
(!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) { // 使用するJREを取得 exit(2); } if (ReadKnownVMs(jvmcfg, JNI_FALSE) < 1) { // 指定されたJVMタイプを検索(jvm.cfg) exit(1); } // JVMタイプをチェック (-client, -server を削除) jvmtype = CheckJvmType(pargc, pargv, JNI_FALSE); if (JLI_StrCmp(jvmtype, "ERROR") == 0) { exit(4); } if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, arch, 0 )) { exit(4); } // LD_LIBRARY_PATH を取得 runpath = getenv(LD_LIBRARY_PATH); execve(...); }
+7.ͷىಈ .BJOΫϥεΛಡΈࠐΉ int JNICALL JavaMain(void * _args) { JavaMainArgs *args
= (JavaMainArgs *)_args; InvocationFunctions ifn = args->ifn; // JVMの初期化 if (!InitializeJVM(&vm, &env, &ifn)) { // ifn->CreateJavaVM(JNI_CreateJavaVM)を実行 exit(1); } mainClass = LoadMainClass(env, mode, what); // メインクラスをロード // JavaFXなどでメインクラスがコマンドラインで指定されていない場合 // JARのマニフェストファイルにある Main-Class の名前を読み込む appClass = GetApplicationClass(env); mainID = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V"); // アプリケーションのコマンドライン引数を設定 mainArgs = CreateApplicationArgs(env, argv, argc); // メインメソッドを実行 (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); // 例外を捕捉 ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1; } http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e74259b3eadc/src/share/bin/java.c
+7.ͷىಈ ৽͘͠࡞͞ΕͨεϨουͰ7.Λ࡞͢Δ int JVMInit(...) { ShowSplashScreen(); return ContinueInNewThread(ifn, threadStackSize, argc,
argv, mode, what, ret); } http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e74259b3eadc/src/solaris/bin/java_md_solinux.c int ContinueInNewThread(...) { JavaMainArgs args; args.argc = argc; args.argv = argv; args.ifn = *ifn; // 新しいスレッドを作成してメインメソッドを実行 rslt = ContinueInNewThread0(JavaMain, threadStackSize, (void*)&args); return (ret != 0) ? ret : rslt; } http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/e74259b3eadc/src/share/bin/java.c
+7.ͷىಈ Ҏ߱ͷॲཧIPUTQPUTSDTIBSFWNҎԼ http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/259c36bd7aea/src/share/vm/prims/jni.cpp#l5162 ΤϯτϦʔϙΠϯτ +/*@$SFBUF+BWB7. ओཁ෦ͷιʔείʔυ http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/259c36bd7aea/src/share/vm/runtime/thread.cpp#l3306 ˠ5ISFBETDSFBUF@WNΛಡΊΕ৭ʑΘ͔ͬͯ͘Δͱࢥ͏
int JLI_Launch(int argc, char ** argv, /* main argc, argc
*/ int jargc, const char** jargv, /* java args */ int appclassc, const char** appclassv, /* app classpath */ const char* fullversion, /* full version defined */ const char* dotversion, /* dot version defined */ const char* pname, /* program name */ const char* lname, /* launcher name */ jboolean javaargs, /* JAVA_ARGS */ jboolean cpwildcard, /* classpath wildcard*/ jboolean javaw, /* windows-only javaw */ jint ergo /* ergonomics class policy */ ) { InitLauncher(javaw); // JLI_SetTraceLauncherしてる DumpState(); if (JLI_IsTraceLauncher()) { int i; printf("Command line args:\n"); for (i = 0; i < argc ; i++) { printf("argv[%d] = %s\n", i, argv[i]); } AddOption("-Dsun.java.launcher.diag=true", NULL); } +7.ͷىಈॲཧ·ΘΓͷখωλ
static void DumpState() { if (!JLI_IsTraceLauncher()) return ; printf("Launcher state:\n");
printf("\tdebug:%s\n", (JLI_IsTraceLauncher() == JNI_TRUE) ? "on" : "off"); printf("\tjavargs:%s\n", (_is_java_args == JNI_TRUE) ? "on" : "off"); printf("\tprogram name:%s\n", GetProgramName()); printf("\tlauncher name:%s\n", GetLauncherName()); printf("\tjavaw:%s\n", (IsJavaw() == JNI_TRUE) ? "on" : "off"); printf("\tfullversion:%s\n", GetFullVersion()); printf("\tdotversion:%s\n", GetDotVersion()); printf("\tergo_policy:"); switch(GetErgoPolicy()) { case NEVER_SERVER_CLASS: printf("NEVER_ACT_AS_A_SERVER_CLASS_MACHINE\n"); break; case ALWAYS_SERVER_CLASS: printf("ALWAYS_ACT_AS_A_SERVER_CLASS_MACHINE\n"); break; default: printf("DEFAULT_ERGONOMICS_POLICY\n"); } } +7.ͷىಈॲཧ·ΘΓͷখωλ
+7.ͷىಈॲཧ·ΘΓͷখωλ void JLI_SetTraceLauncher() { if (getenv(JLDEBUG_ENV_ENTRY) != 0) { _launcher_debug
= JNI_TRUE; JLI_TraceLauncher("----%s----\n", JLDEBUG_ENV_ENTRY); } } openjdk/jdk8u/jdk/src/share/bin/jli_util.h 33:#define JLDEBUG_ENV_ENTRY "_JAVA_LAUNCHER_DEBUG"
$ export _JAVA_LAUNCHER_DEBUG=1 $ java Hello ----_JAVA_LAUNCHER_DEBUG---- Launcher state: debug:on
javargs:off program name:java launcher name:java javaw:off fullversion:1.8.0_131-b11 dotversion:1.8 ergo_policy:DEFAULT_ERGONOMICS_POLICY Command line args: argv[0] = /usr/bin/java argv[1] = Hello JRE path is /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre jvm.cfg[0] = ->-server<- jvm.cfg[1] = ->-client<- 6957 micro seconds to parse jvm.cfg Default VM: server ~ +7.ͷىಈॲཧ·ΘΓͷখωλ
·ͱΊ ͜ΕΒͷ༻ޠ֮ͯ͑͢Δඞཁͳ͍ ग़͖ͯͨͱ͖ʹௐΕ͍͍ ࠓग़͖ͯͨ୯ޠৗۀͰ༻͠·ͤΜ ಡΜͰ͍Δͱཪٕ෦ಈ࡞ʹৄ͘͠ͳͬͯ͘ΔͷͰָ͘͠ͳͬͯ͘Δ
͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ
4ZODISPOJ[BUJPOBOE0CKFDU-PDLJOH )PU4QPUVOEFSUIF)PPE -PDLJOHBOE4ZODISPOJ[BUJPO +BWBΦϒδΣΫτͷϝϞϦߏ &WFSZUIJOH*&WFS-FBSOFE"CPVU+7.1FSGPSNBODF5VOJOH!5XJUUFS +%,+7.*NQSPWFNFOUT ࢀߟࢿྉ https://www.infoscoop.org/blogjp/2014/06/16/java-objects-memory-structure/ https://www.slideshare.net/aszegedi/everything-i-ever-learned-about-jvm-performance-tuning-twitter https://www.slideshare.net/nminoru_jp/jvm-readingsynchronization
https://www.infoq.com/presentations/hotspot-memory-data-structures https://wiki.openjdk.java.net/display/HotSpot/Synchronization http://otndnld.oracle.co.jp/ondemand/javaday2014/pdf/C2-JavaDay-304328.pdf