JVMã¯ã©ã®ããã«ããŠæ°ãããªããžã§ã¯ããäœæããŸããïŒ new Object()
ãèšè¿°ãããšã©ããªããŸããïŒ
äŒè°ã§ã¯ãã¹ã¬ããããŒã«ã«ã¢ãã±ãŒã·ã§ã³ãããã¡ãŒïŒã¹ã¬ããããŒã«ã«ã¢ãã±ãŒã·ã§ã³ãããã¡ãŒïŒã䜿çšããŠãªããžã§ã¯ããå²ãåœãŠããšå®æçã«èšããŸãïŒåã¹ã¬ããã«æä»çã«å²ãåœãŠãããã¡ã¢ãªé åãåæã®æ¬ åŠã«ãããªããžã§ã¯ãã®äœæãéåžžã«é«éã§ãã
ããããé©åãªãµã€ãºã®TLAB'aãéžæããæ¹æ³ã¯ïŒ TLABã®ãµã€ãºã®10ïŒ
ãå²ãåœãŠãå¿
èŠãããã9ïŒ
ã®ã¿ãç¡æã®å Žåã¯ã©ãããã°ããã§ããïŒ ãªããžã§ã¯ããTLABã®å€éšã«å²ãåœãŠãããšã¯ã§ããŸããïŒ å²ãåœãŠãããã¡ã¢ãªããªã»ãããããã®ã¯ãã€ã§ããïŒ
ãããã®è³ªåããããã¹ãŠã®çããèŠã€ããããªãã£ãã®ã§ãç¶æ³ãä¿®æ£ããèšäºãæžãããšã«ããŸããã
èªãåã«ãããçš®ã®ã¬ããŒãžã³ã¬ã¯ã¿ãã©ã®ããã«æ©èœããããèŠããŠãããšåœ¹ç«ã¡ãŸãïŒããšãã°ã ãã®äžé£ã®èšäºãèªãã åŸïŒã
ã¯ããã«
æ°ããæœèšãäœæããã«ã¯ã©ã®ãããªæé ãå¿
èŠã§ããïŒ
ãŸããå¿
èŠãªãµã€ãºã®æªäœ¿çšã®ã¡ã¢ãªé åãèŠã€ããå¿
èŠããããæ¬¡ã«ãªããžã§ã¯ããåæåããå¿
èŠããããŸãïŒã¡ã¢ãªããŒãã«ããããã€ãã®å
éšæ§é ïŒ getClass()
ãåŒã³åºããšãããªããžã§ã¯ãã§åæãããšããªã©ã«äœ¿çšãããæ
å ±ïŒãåæåããæåŸã«ã³ã³ã¹ãã©ã¯ã¿ãåŒã³åºãå¿
èŠããããŸãã
ãã®èšäºã¯æ¬¡ã®ããã«æ§æãããŠããŸããæåã«çè«äžäœãèµ·ããããçè§£ããããšããæ¬¡ã«äœããã®æ¹æ³ã§JVMã®å
éšã«å
¥ãããã¹ãŠãå®éã«èµ·ããæ§åã確èªããæåŸã«ããã€ãã®ãã³ãããŒã¯ãäœæããŠç¢ºèªããŸãã
å
責äºé
ïŒäžéšã®éšåã¯ãäžè¬æ§ã倱ããã«æå³çã«ç°¡ç¥åãããŠããŸãã ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãšããã°ãå§çž®ã³ã¬ã¯ã¿ãŒãããã³ã¢ãã¬ã¹ç©ºéãšèšãã°ãè¥ãäžä»£ã®ãšãã³ã§ãã ä»ã®[æšæºãŸãã¯åºãç¥ãããŠãã]ã¬ããŒãžã³ã¬ã¯ã¿ãŒã®å Žåã詳现ã¯å€æŽãããå¯èœæ§ããããŸãããããŸã倧ãããããŸããã
TLAB 101
æåã®éšåã¯ããªããžã§ã¯ãã«ç©ºãã¡ã¢ãªãå²ãåœãŠãããšã§ãã
äžè¬çãªã±ãŒã¹ã§ã¯ã广çãªã¡ã¢ãªã®å²ãåœãŠã¯ãçã¿ãèŠãã¿ããã©ãŽã³ã«æºã¡ãéèŠãªã¿ã¹ã¯ã§ãã ããšãã°ã2ã®åæ°ã®ãµã€ãºã®ãªã³ã¯ãªã¹ããäœæãããããããæ€çŽ¢ãããå¿
èŠã«å¿ããŠã¡ã¢ãªé åãåãåãããŠããããªã¹ãããå¥ã®ãªã¹ãïŒå¥å
ããã£ã¢ãã±ãŒã¿ãŒ ïŒã«ç§»åãã
ãŸã ã
幞ããªããšã«ãJavaãã·ã³ã«ã¯ã¬ããŒãžã³ã¬ã¯ã¿ãŒãããããžã§ãã®é£ããéšåãæ
ã£ãŠããŸãã è¥ãäžä»£ãçµã¿ç«ãŠãããã»ã¹ã§ã¯ããã¹ãŠã®çããŠãããªããžã§ã¯ãããµãã€ããŒã¹ããŒã¹ã«ç§»åãããedenã«1ã€ã®å€§ããªé£ç¶ãã空ãã¡ã¢ãªé åãæ®ãããŸãã
JVMã®ã¡ã¢ãªãGCãè§£æŸãããããã¢ãã±ãŒã¿ã¯ãã®ç©ºãã¡ã¢ãªã®å Žæãç¥ãã ãã§ãããå®éããã®ç©ºãã¡ã¢ãªãžã®1ã€ã®ãã€ã³ã¿ãžã®ã¢ã¯ã»ã¹ãå¶åŸ¡ããŸãã ã€ãŸããå²ãåœãŠã¯éåžžã«åçŽã§ãªããã°ãªããŸãã ãããŒãšè¹ã§æ§æãããŠããŸã ïŒãã€ã³ã¿ã«ãªããžã§ã¯ãã®ãµã€ãºã远å ããŠãedenãšã¡ã¢ãªãè§£æŸããå¿
èŠããããŸãïŒãã®ææ³ã¯bump-the-pointerãšåŒã°ããŸã ïŒã
ãã®å Žåãè€æ°ã®ã¹ã¬ãããã¡ã¢ãªãå²ãåœãŠãããšãã§ãããããäœããã®åœ¢åŒã®åæãå¿
èŠã§ãã æãç°¡åãªæ¹æ³ïŒããŒãé åãŸãã¯ãã€ã³ã¿ãŒã®ã¢ãããã¯å¢åã®ãããã¯ïŒãè¡ããšãã¡ã¢ãªãŒå²ãåœãŠãç°¡åã«ããã«ããã¯ã«ãªãå¯èœæ§ããããããJVMéçºè
ã¯ãã³ããã€ã³ã¿ãŒã䜿çšããŠä»¥åã®ã¢ã€ãã¢ãéçºããŸããïŒåã¹ã¬ããã«ã¯ãããã ãã«å±ãã倧ããªã¡ã¢ãªãã£ã³ã¯ãå²ãåœãŠãããŸãã ãã®ãããªãããã¡å
ã®å²ãåœãŠã¯ãå¯èœãªéããã€ã³ã¿ã®åãå¢åã§çºçããŸãïŒãã ãããã§ã«ããŒã«ã«ã§ãåæã¯è¡ãããŠããŸããïŒãçŸåšã®é åãçµäºãããã³ã«æ°ããé åãèŠæ±ãããŸãã ãã®é åã¯ã ã¹ã¬ããããŒã«ã«å²ãåœãŠãããã¡ãšåŒã°ããŸã ã ããŒãé åãæåã®ã¬ãã«ã«ãããçŸåšã®ã¹ã¬ããã2çªç®ã®TLABã«ãããäžçš®ã®éå±€çãªãã³ããã€ã³ã¿ãŒã倿ããŸãã äžéšã®ãŠãŒã¶ãŒã¯ããã§åæ¢ã§ãã ããããã¡ãŒå
ã®ãããã¡ãŒãéå±€çã«ã¹ã¿ãã¯ããããšãã§ããŸãã ã

ã»ãšãã©ã®å Žåãå²ãåœãŠã¯éåžžã«é«éã§ããããæ°åœä»€ã§å®è¡ãããæ¬¡ã®ããã«ãªããŸãã
start = currentThread.tlabTop; end = start + sizeof(Object.class); if (end > currentThread.tlabEnd) { goto slow_path; } currentThread.setTlabTop(end); callConstructor(start, end);
ããŸãã«ãè¯ããããªã®ã§ãPrintAssemblyã䜿çšããŠã java.lang.Object
ãäœæããã¡ãœãããã©ã®ããã«ã³ã³ãã€ã«ãããããèŠãŠã¿ãŸããã ã
; Hotspot machinery skipped mov 0x60(%r15),%rax ; start = tlabTop lea 0x10(%rax),%rdi ; end = start + sizeof(Object) cmp 0x70(%r15),%rdi ; if (end > tlabEnd) ja 0x00000001032b22b5 ; goto slow_path mov %rdi,0x60(%r15) ; tlabTop = end ; Object initialization skipped
%r15
ã¬ãžã¹ã¿ã«ã¯åžžã«VMã¹ã¬ãããžã®ãã€ã³ã¿ãŒãå«ãŸãããšããç§å¯ã®ç¥èããããŸãïŒåæ
çãªéžè±ïŒãã®äžå€åŒã«ãããã¹ã¬ããããŒã«ã«ãšThread.currentThread()
éåžžã«é«éã«åäœããŸãïŒãæåŸ
ããŠããã åæã«ãJITã³ã³ãã€ã©ãŒãåŒã³åºãã¡ãœããã«å²ãåœãŠãçŽæ¥æ¿å
¥ããããšã«æ³šæããŠãã ããã
ãã®ããã«ããŠãJVMã¯ïŒã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãèæ
®ããã«ïŒã»ãšãã©ç¡æã§ã1ããŒã¹ã®åœä»€ã«å¯ŸããŠæ°ãããªããžã§ã¯ããäœæããã¡ã¢ãªã®ã¯ãªã¢ãšããã©ã°ã®è²¬ä»»ãGCã«ç§»ããŸãã è¯ãããŒãã¹ã¯ãå²ãåœãŠãããããŒã¿ã®è¡ã®ããŒã«ãªãã£ã§ããããã¯ãå€å
žçãªã¢ãã±ãŒã¿ãŒã§ã¯ä¿èšŒã§ããªãå ŽåããããŸãã ãã®ãããªå±ææ§ãå
žåçãªã¢ããªã±ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ã«äžãã圱é¿ã«ã€ããŠã®å
šäœçãªç ç©¶ããããŸãã ã¹ãã€ã©ãŒã¢ã©ãŒã ïŒGCã®è² è·ãå¢å ããŠããã«ããããããããã¹ãŠãå°ãéããªããŸãã
äœãèµ·ãã£ãŠãããã«å¯ŸããTLABãµã€ãºã®åœ±é¿
TLABã®ãµã€ãºã¯ã©ã®ãããã§ããïŒ æåã®è¿äŒŒãšããŠããããã¡ãµã€ãºãå°ããã»ã©ãã¡ã¢ãªã®å²ãåœãŠãã¹ããŒãã©ã³ããééããé »åºŠãé«ããªããããTLABãããå€ãå®è¡ããå¿
èŠããããšæ³å®ããã®ãåççã§ãã
ãã ããå¥ã®åé¡ããããŸãã å
éšãã©ã°ã¡ã³ããŒã·ã§ã³ã§ãã
TLABã®ãµã€ãºã2ã¡ã¬ãã€ãã§ãedené åïŒTLABã®å²ãåœãŠå
ïŒã500ã¡ã¬ãã€ããå æããã¢ããªã±ãŒã·ã§ã³ã«50ã¹ããªãŒã ãããç¶æ³ãèããŸãã ããŒãå
ã®æ°ããTLABã®å ŽæããªããªããšãTLABã䜿ãæããæåã®ã¹ã¬ãããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãããªã¬ãŒããŸãã TLABã±åäžã«æºãããããšä»®å®ãããšïŒå®éã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããã§ã¯ãªããããããŸããïŒãå¹³åããŠãæ®ãã®TLABã¯çŽååã«ãªããŸãã ã€ãŸããå¥ã®0.5 * 50 * 2 == 50
ã¡ã¬ãã€ãã®æªå²ãåœãŠã¡ã¢ãªïŒ 0.5 * 50 * 2 == 50
10ïŒ
ïŒãããå Žåãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãéå§ãããŸãã ããŸãåäœããŸãããã¡ã¢ãªã®ããªãã®éšåã¯ãŸã 空ããŠããŸãããGCã¯ãŸã åŒã³åºãããŠããŸãã

TLABã®ãµã€ãºãŸãã¯ã¹ã¬ããã®æ°ãå¢ããç¶ãããšãã¡ã¢ãªæå€±ãç·åœ¢çã«å¢å ããTLABã¯å²ãåœãŠãé«éåããŸãããã¢ããªã±ãŒã·ã§ã³å
šäœã®é床ãäœäžããåã³ã¬ããŒãžã³ã¬ã¯ã¿ãŒã«è² æ
ããããããšãããããŸãã
TLABã«ãŸã å Žæãããããæ°ãããªããžã§ã¯ãã倧ããããå Žåã¯ã©ãã§ããããïŒ å€ããããã¡ãæšãŠãŠæ°ãããããã¡ãå²ãåœãŠããšãæçåãå¢å ããã ãã§ããããã®ãããªç¶æ³ã§åžžã«edenã§ãªããžã§ã¯ããçŽæ¥äœæãããšãã¢ããªã±ãŒã·ã§ã³ã®åäœãé
ããªããŸããïŒ
äžè¬ã«ãäœããã¹ããã¯æç¢ºã§ã¯ãããŸããã ç¥ç§çãªå®æ°ãããŒãã³ãŒãã£ã³ã°ããŠïŒãã¥ãŒãªã¹ãã£ãã¯ã€ã³ã©ã€ã³åã®ããã«è¡ãããããã«ïŒãéçºè
ã«ãµã€ãºãäžããã¢ããªã±ãŒã·ã§ã³ããšã«åå¥ã«ïŒä¿¡ããããªãã»ã©äŸ¿å©ã«ïŒã«ã¹ã¿ãã€ãºããããšãã§ããŸãã
ã©ãããïŒ
宿°ãéžæããããšã¯ãããããä»äºã§ãããSunã®ãšã³ãžãã¢ã¯çµ¶æãããéã«è¡ããŸããïŒãµã€ãºãæå®ãã代ããã«ãæçåã®å²åã瀺ãããŸã-è¿
éãªå²ãåœãŠã®ããã«ç ç²ã«ããæºåãã§ããŠããããŒãã®äžéšã§ãããJVMã¯ãããäœããã®æ¹æ³ã§ææ¡ããŸãã TLABWasteTargetPercent
ãã©ã¡ãŒã¿ãŒããããæ
åœããããã©ã«ãã¯1ïŒ
ã§ãã
ã¹ã¬ããã«ããã¡ã¢ãªå²ãåœãŠã®åäžæ§ã«é¢ããåã仮説ã䜿çšããŠãåçŽãªæ¹çšåŒtlab_size * threads_count * 1/2 = eden_size * waste_percent
ãŸãã
edenã®10ïŒ
ãå¯ä»ããæºåãã§ããŠããå Žåãã¹ã¬ããã¯50åãããedenã¯500ã¡ã¬ãã€ããå æããŸããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã®éå§æã«ãåå空ã®TLABã§50ã¡ã¬ãã€ããè§£æŸã§ããŸããã€ãŸãããã®äŸã§ã¯ãTLABã®ãµã€ãºã¯2ã¡ã¬ãã€ãã«ãªããŸãã
ãã®ã¢ãããŒãã«ã¯éå€§ãªæ¬ èœããããŸãããã¹ãŠã®ã¹ã¬ãããçããå²ãåœãŠããããšããä»®å®ã䜿çšãããŸãããããã¯ã»ãšãã©åžžã«çå®ã§ã¯ãããŸããã æãæ¿ããã¹ããªãŒã ã®å²ãåœãŠçã«æ°å€ã調æŽããããšã¯æãŸãããããŸãã;ãŸããç§ã¯åœŒãã®ããé
ãååïŒäŸãã°ãã¹ã±ãžã¥ãŒã«ãããåŽåè
ïŒãæãããããããŸããã ããã«ãå
žåçãªã¢ããªã±ãŒã·ã§ã³ã§ã¯ïŒããšãã°ããæ°ã«å
¥ãã®ã¢ããªãµãŒããŒã®ãã¬ãããã«ã«ïŒæ°çŸã®ã¹ã¬ããããããæ·±å»ãªè² è·ãªãã«æ°ãããªããžã§ã¯ããäœæããã¹ã¬ããã¯ãããããã§ãããããäœããã®åœ¢ã§èæ
®ããå¿
èŠããããŸãã ãTLABã®ãµã€ãºã®10ïŒ
ãå²ãåœãŠãå¿
èŠãããã9ïŒ
ã ããç¡æã®å Žåã¯ã©ãããã°ããã§ããïŒããšãã質åãæãåºããšãããã¯å®å
šã«èªæã§ã¯ãªããªããŸãã
ããã°ã§æšæž¬ãããèŠãããããã«ã¯è©³çްãå€ãããã®ã§ãä»åºŠã¯ãã¹ãŠãå®éã«ã©ã®ããã«æ©èœãããã調ã¹ãŸãããããããã¹ãããã®ãœãŒã¹ã³ãŒããèŠãŠã¿ãŸãããã
jdk9ãŠã£ã¶ãŒãã䜿çšããŸãããããã«CMakeLists.txtããããŸããããã䜿çšããŠãæ
è¡ãç¹°ãè¿ãããå Žåã«CLionãåäœããŸãã
ãŠãµã®ã®ç©Žãåã
é¢å¿ã®ãããã¡ã€ã«ã¯ãæåã®grepããèŠã€ããã ã threadLocalAllocBuffer.cppãšåŒã°ããŸã ãããã¯ããããã¡ãŒã®æ§é ãèšè¿°ããŠããŸãã ã¯ã©ã¹ã¯ãããã¡ãèšè¿°ãããšããäºå®ã«ãããããããã¹ã¬ããããšã«1åäœæãããæ°ããTLABãå²ãåœãŠããããšãã«åå©çšããããšåæã«ãTLABã®äœ¿çšã«é¢ããããŸããŸãªçµ±èšãããã«æ ŒçŽãããŸãã
JITã³ã³ãã€ã©ãŒãçè§£ããã«ã¯ãJITã³ã³ãã€ã©ãŒã®ããã«èããå¿
èŠããããŸãã ãããã£ãŠãåæåæåãããã«ã¹ãããããæ°ããã¹ã¬ããçšã®ãããã¡ãŒãäœæããŠããã©ã«ãå€ãèšç®ããåã¢ã»ã³ããªã®æåŸã«ãã¹ãŠã®ã¹ã¬ããã«å¯ŸããŠåŒã³åºãããresize
ã¡ãœããã調ã¹ãŸãã
void ThreadLocalAllocBuffer::resize() {
ããïŒ åã¹ã¬ããã«ã€ããŠããã®å²ãåœãŠã®åŒ·åºŠã远跡ããããã®å²ãåœãŠãšå®æ°_target_refills
ïŒã2ã€ã®ã¢ã»ã³ããªéã§ã¹ã¬ããã«èŠæ±ããTLABã®æ°ããšããŠæ
éã«çœ²åãããŸãïŒã«å¿ããŠãæ°ãããµã€ãºãèšç®ãããŸãã
_target_refills
äžåºŠåæåãããŸãïŒ
ããã¯ãŸãã«äžèšã§ä»®å®ãã仮説ã§ãããTLABã®ãµã€ãºã®ä»£ããã«ãã¹ããªãŒã ã®æ°ããTLABã®ãªã¯ãšã¹ãæ°ãèšç®ãããŸãã ã¢ã»ã³ããªæã«ãã¹ãŠã®ã¹ã¬ãããæå€§x%
空ãã¡ã¢ãªãæã€ããã«ã¯ãåã¹ã¬ããã®TLABãµã€ãºãåèšã¡ã¢ãªã®2x%
ã§ããå¿
èŠããããŸããããã¯éåžžãã¢ã»ã³ããªéã§å²ãåœãŠãããŸãã 1
ã2x
ãããšãå¿
èŠãªæ°ã®ã¯ãšãªã ããåŸãããŸãã
ã¹ã¬ããå²ãåœãŠå
±æã¯ããã€ãæŽæ°ããå¿
èŠããããŸãã åã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã®éå§æã«ããã¹ãŠã®ãããŒã®çµ±èšãæŽæ°ãããŸããããã¯ã accumulate_statistics
ã¡ãœããã«ãããŸãã
- ã¹ã¬ãããTLABãå°ãªããšã1åæŽæ°ãããã©ããã確èªããŸãã äœãããªãïŒãŸãã¯å°ãªããšãå²ãåœãŠãªãïŒã¹ã¬ããã®ãµã€ãºãåèšç®ããå¿
èŠã¯ãããŸããã
- èšç®ã§ã®ãã«GCãŸãã¯ç
çåŠçã±ãŒã¹ïŒããšãã°ã
System.gc()
æç€ºçãªåŒã³åºãSystem.gc()
ã®åœ±é¿ãåé¿ããããã«ãedenã®ååã䜿çšããããã©ããã確èªããŸãã - æåŸã«ãedenã®äœããŒã»ã³ããã¹ããªãŒã ã䜿çšããããèæ
®ããå²ãåœãŠã®ã·ã§ã¢ãæŽæ°ããŸãã
- ã¹ã¬ãããã©ã®ããã«TLABã䜿çšããããå²ãåœãŠãããæ¹æ³ãšéãããã³ã¡ã¢ãªãç¡é§ã«ãªã£ãéã®çµ±èšãæŽæ°ããŸãã
ã¢ã»ã³ããªã®é »åºŠãšãã¬ããŒãžã³ã¬ã¯ã¿ãŒã®äžæŽåãšã¹ããªãŒã ã®èŠæ±ã«é¢é£ããããŸããŸãªå²ãåœãŠãã¿ãŒã³ã«èµ·å ããããŸããŸãªäžå®å®ãªåœ±é¿ãåé¿ããããã«ãå²ãåœãŠã®ã·ã§ã¢ã¯åãªãæ°åã§ã¯ãªããæåŸã®Nåã®ã¢ã»ã³ããªã®å¹³åãç¶æããææ°å éç§»åå¹³åã§ãã JVMã«ã¯ãã¹ãŠã®ç¬èªã®ããŒãããããã®å ŽæãäŸå€ã§ã¯ãããŸããTLABAllocationWeight
ãã©ã°ã¯ãå¹³åå€ãå€ãå€ãã©ãã ãæ©ãå¿ããããå¶åŸ¡ããŸãïŒèª°ãããã®ãã©ã°ã®å€ã倿Žãããããã§ã¯ãããŸããïŒã
çµæ
åãåã£ãæ
å ±ã¯ãTLABã®ãµã€ãºã«é¢ãã質åã«çããã®ã«ååã§ãã
- JVMã¯ãæçåã«äœ¿çšã§ããã¡ã¢ãªéãèªèããŠããŸãã ãã®å€ãããã¹ã¬ãããã¬ããŒãžã³ã¬ã¯ã·ã§ã³éã§èŠæ±ããTLABã®æ°ãèšç®ãããŸãã
- JVMã¯ãåã¹ã¬ããã䜿çšããã¡ã¢ãªéãç£èŠãããããã®å€ãå¹³æ»åããŸãã
- åã¹ã¬ããã¯ã䜿çšããã¡ã¢ãªã«æ¯äŸããŠTLABã®ãµã€ãºãåãåããŸãã ããã«ãããã¹ã¬ããéã®äžåçãªå²ãåœãŠã®åé¡ã解決ãããå¹³åããŠãã¹ãŠãè¿
éã«å²ãåœãŠãããŸãããã¡ã¢ãªãã»ãšãã©æ¶è²»ããŸããã

ã¢ããªã±ãŒã·ã§ã³ã«100åã®ã¹ã¬ãããããããã®ãã¡3åããã€ããšã¡ã€ã³ã§ãŠãŒã¶ãŒã®ãªã¯ãšã¹ããåŠçããã¿ã€ããŒã®2åãäœããã®è£å©ã¢ã¯ãã£ããã£ã«é¢äžããä»ã®ãã¹ãŠãã¢ã€ãã«ç¶æ
ã®å Žåãã¹ã¬ããã®æåã®ã°ã«ãŒãã¯å€§ããªTLABãåãåãã2çªç®ã¯éåžžã«å°ãããæ®ãã¯ãã¹ãŠããã©ã«ãå€ã«ãªããŸãã ãããŠãæè¯ã®éšåã¯ããã¹ãŠã®ã¹ã¬ããã®ãé
ããå²ãåœãŠïŒTLABèŠæ±ïŒã®æ°ãåãã§ããããšã§ãã
C1ã§ã®å²ãåœãŠ
TLABã®ãµã€ãºãæŽçãããŸããã é ããŸã§è¡ããªãããã«ããœãŒã¹ãããæ·±ãæãäžããŠãTLABãé«éãäœéãæ¬åœã«äœéã®ãšãã«éç«ã£ãŠããããšã確èªããŠãã ããã
ããã§ã¯ã1ã€ã®ã¯ã©ã¹ã ãã§ã¯å¯Ÿå¿ã§ããã new
æŒç®åãäœã«ã³ã³ãã€ã«ããããã調ã¹ãå¿
èŠããããŸãã å€å·æ§ã®è³æå·ãåé¿ããããã«ãã¯ã©ã€ã¢ã³ãã³ã³ãã€ã©ïŒC1ïŒã®ã³ãŒããèŠãŠã¿ãŸãããïŒãµãŒããŒã³ã³ãã€ã©ãããã¯ããã«ã·ã³ãã«ã§çè§£ãããããäžçã®å
šäœåããã説æããŠããŸããJavaã®new
ãã®ã¯éåžžã«äººæ°ããããããååãªæé©åãè¡ãããŠããŸãã
C1_MacroAssembler::allocate_object
ã§ã®ãªããžã§ã¯ãã®å²ãåœãŠãšåæåãèšè¿°ããC1_MacroAssembler::allocate_object
ãã¡ã¢ãªããã°ããå²ãåœãŠãããšãã§ããªãã£ããšãã«å®è¡ãããRuntime1::generate_code_for
2ã€ã®ã¡ãœããã«èå³ããããŸãã
ãªããžã§ã¯ããåžžã«è¿
éã«äœæã§ãããã©ããã確èªããã®ã¯è峿·±ãããšã§ãããäœ¿çšæ³ãèŠã€ããããã§ãŒã³ã¯ã instanceKlass.hppã®ãã®ã³ã¡ã³ãã«ã€ãªãããŸã ã
ãã®ããšãããéåžžã«å€§ããªãªããžã§ã¯ãïŒããã©ã«ãã§ã¯128ãããã€ããè¶
ããïŒãšãã¡ã€ãã©ã€ãºå¯èœãªã¯ã©ã¹ããJVMã§åžžã«é
ãåŒã³åºããè¡ãããšãæããã«ãªããŸãã ïŒãªããªã-æœè±¡ã¯ã©ã¹ã¯ã©ããšé¢ä¿ãããã®ã§ããããïŒïŒ
ãã®ã¡ã¢ãåããå²ãåœãŠããã»ã¹ã«æ»ããŸãã
tlab_allocate-ãªããžã§ã¯ãããã°ããå²ãåœãŠãããšãã詊ã¿ãPrintAssemblyãèŠããšãã«ãã§ã«èŠãã³ãŒããšãŸã£ããåãã§ãã 倿ããå Žåãããã§å²ãåœãŠãçµäºãããªããžã§ã¯ãã®åæåã«é²ã¿ãŸãã
tlab_refill-æ°ããTLABã®å²ãåœãŠã詊ã¿ãŸãã è峿·±ããã§ãã¯ã䜿çšããŠããã®ã¡ãœããã¯ãæ°ããTLABãå²ãåœãŠãïŒå€ãTLABãç Žæ£ããïŒãããªããžã§ã¯ããedenã«çŽæ¥å²ãåœãŠãŠå€ãTLABãæ®ãããæ±ºå®ããŸãã
tlab_refill_waste_limit
ã¯ãTLABã®ãµã€ãºã«ã®ã¿è²¬ä»»ãããã1ã€ã®ãªããžã§ã¯ããå²ãåœãŠãããã«ç ç²ã«ããæºåãã§ããŠããŸããã ããã©ã«ãå€ã¯çŸåšã®TLABãµã€ãºã®1.5%
ã§ãïŒãã¡ãããããã«ã¯TLABRefillWasteFraction
ãã©ã¡ãŒã¿ãŒããããŸããããã¯çªç¶ 64ã®å€ãæã¡ãå€èªäœã¯çŸåšã®TLABãµã€ãºããã®ãã©ã¡ãŒã¿ãŒã®å€ã§å²ã£ããã®ãšèŠãªãããŸãïŒã ãã®å¶éã¯ã倱æããã±ãŒã¹ã§ã®äœäžãé¿ããããã«ãé
ãå²ãåœãŠããšã«åŒãäžããããåGCãµã€ã¯ã«ã®çµããã«ãªã»ãããããŸãã 1ã€å°ãªã質åã
- eden_allocate -edenã§ã¡ã¢ãªïŒãªããžã§ã¯ããŸãã¯TLABïŒãå²ãåœãŠãããšããŸãã ãã®å Žæã¯TLABã§ã®å²ãåœãŠã«éåžžã«äŒŒãŠããŸãïŒå Žæããããã©ããã確èªããããå Žåã¯ã
lock cmpxchg
åœä»€ã䜿çšããŠã¢ãããã¯ã«ã¡ã¢ãªãååŸãããªãå Žåã¯äœéãã¹ã«é²ã¿ãŸãã edenã§ã®å²ãåœãŠã¯åŸ
æ©ããªãŒã§ã¯ãããŸããã2ã€ã®ã¹ã¬ãããåæã«edenã§äœããå²ãåœãŠãããšãããšãäœããã®ç¢ºçã§ãã®ãã¡ã®1ã€ã倱æããããäžåºŠç¹°ãè¿ãå¿
èŠããããŸãã
JVMã¢ããã³ãŒã«
edenã§ã¡ã¢ãªãå²ãåœãŠãããšãã§ããªãã£ãå ŽåãJVMã§åŒã³åºããè¡ããã InstanceKlass::allocate_instance
ã€ãªãããŸãã åŒã³åºãèªäœã®åã«ãå€ãã®è£å©çãªäœæ¥ãå®è¡ãããŸã-GCã®ç¹å¥ãªæ§é ãèšå®ããã åŒã³åºãèŠçŽã«å¯Ÿå¿ããããã«å¿
èŠãªãã¬ãŒã ãäœæããããããæäœã¯éããããŸããã
ããããã®ã³ãŒããããã衚é¢çãªèª¬æã¯1ã€ããã§ããªãã®ã§ãã ããéå±ãããªãããã«ãããããã®äœæ¥ã¹ããŒã ã®ã¿ã瀺ããŸãã
- æåã«ãJVMã¯çŸåšã®ã¬ããŒãžã³ã¬ã¯ã¿ãŒã®ç¹å®ã®ã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠã¡ã¢ãªãå²ãåœãŠãããšããŸãã äžèšãšåãäžé£ã®åŒã³åºããè¡ãããŸããæåã«TLABããå²ãåœãŠã詊è¡ããæ¬¡ã«ããŒãããTLABãå²ãåœãŠãŠãªããžã§ã¯ããäœæããŸãã
- 倱æããå Žåãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ãåŒã³åºãããŸãã GCãªãŒããŒãããå¶éãã©ãããè¶
ãããããããŸããŸãªGCéç¥ããã°ãããã³å²ãåœãŠã«é¢ä¿ããªããã®ä»ã®ãã§ãã¯ãåãå Žæã®ã©ããã«é¢ä¿ããŠããŸãã
- ã¬ããŒãžã³ã¬ã¯ã·ã§ã³ã圹ã«ç«ããªãå Žåã¯ãæ§äžä»£ã«çŽæ¥å²ãåœãŠãããšããŸãïŒããã§ãåäœã¯éžæããGCã¢ã«ãŽãªãºã ã«äŸåããŸãïŒã倱æããå Žåã¯ãå¥ã®ã¢ã»ã³ããªãšãªããžã§ã¯ãäœæã®è©Šè¡ãçºçããŸãã
OutOfMemoryError
ã - ãªããžã§ã¯ããæ£åžžã«äœæããããšããããæéããã¡ã€ãã©ã€ãºå¯èœãã©ããããã§ãã¯ãããããã§ããã°ãç»é²ãããŸããããã¯ã
Finalizer#register
ã¡ãœããã®åŒã³åºãã§æ§æãããŸãïŒãªããã®ã¯ã©ã¹ãæšæºã©ã€ãã©ãªã«ããã®ãçåã«æã£ãŠããŸããããæç€ºçã«äœ¿çšãããŠããŸãããïŒïŒã ã¡ãœããèªäœã¯ãããªãåã«æç€ºçã«äœæãããŸããããã¡ã€ãã©ã€ã¶ãªããžã§ã¯ããäœæãããã°ããŒãã«ïŒåæã®ãŸãŸïŒããã¯ã®äžã§ããªã³ã¯ãªã¹ãã«è¿œå ãããŸãïŒãªããžã§ã¯ãã¯ãã®åŸããã¡ã€ãã©ã€ãºããã³åéãããŸãïŒã ããã¯ãJVMã§ã®ç¡æ¡ä»¶åŒã³åºããšïŒéšåçã«ïŒãæ¬åœã«å¿
èŠãªå Žåã§ãfinalizeã¡ãœããã䜿çšããªãããšããã¢ããã€ã¹ã«ãã£ãŠæ£åœåãããŸãã
ãã®çµæãå²ãåœãŠã«é¢ããã»ãšãã©ãã¹ãŠãããããŸããããªããžã§ã¯ãã¯ããã«å²ãåœãŠãããTLABã¯ããã«ãã£ã±ãã«ãªãããªããžã§ã¯ãã¯edenã§ããã«å²ãåœãŠãããäžéšã¯JVMã§æ¥ãã§åŒã³åºãããŸãã
é
ãå²ãåœãŠã®ç£èŠ
ã¡ã¢ãªã®å²ãåœãŠæ¹æ³ã¯ããããŸãããããã®æ
å ±ãã©ããããã¯ãŸã ãããŸããã
äžèšã®ã©ããã§ããã¹ãŠã®çµ±èšïŒé
ãå²ãåœãŠããªãã£ã«ã®å¹³åæ°ãå²ãåœãŠãããŒã®æ°ãå
éšãã©ã°ã¡ã³ããŒã·ã§ã³ã«ããæå€±ïŒãã©ããã«èšé²ããããšæžããŸããã
- â perf data, hsperfdata, jcmd sun.jvmstat.monitor
API.
, Oracle JDK, JFR ( API, OpenJDK), -.
? , Twitter JVM team, , .
Prefetch
, - prefetch', .
Prefetch â , , , , ( ) , . Prefetch , , , , (, ) , , .
ãããã¹ãããã§ã¯ãããªãã§ããã¯C2åºæã®æé©åã§ãããããC1ã³ãŒãã§ã¯èšåãããŠããŸãããæé©åã®æ§æã¯æ¬¡ã®ãšããã§ããTLABã§ã®å²ãåœãŠäžã«ãå²ãåœãŠããããªããžã§ã¯ãã®ããåŸãã«ãããã£ãã·ã¥ã¡ã¢ãªã«ããŒãããåœä»€ãçæãããŸãã Javaã¢ããªã±ãŒã·ã§ã³ã¯å¹³åããŠ1ã€ãŸãã¯è€æ°ã®å²ãåœãŠãè¡ããããåŸç¶ã®å²ãåœãŠã®ããã«ã¡ã¢ãªãããªããŒãããããšã¯éåžžã«è¯ãèãã®ããã§ãã
prefetch' , AllocatePrefetchStyle
: prefetch , , , . AllocatePrefetchInstr
, prefetch : L1- (, - ), L3 : , .ad .
, JVM-, SPECjbb- Java - , ( , , , ).
, , . C1-, ARM â , .
C1_MacroAssembler::initialize_object
:
. â mark word ,
, identity hashcode ( biased locking) , klass pointer, â , metaspace, java.lang.Class
.

32 64. , 12 ( , 16).
, ZeroTLAB
. :
, , . C2- , . .
- StoreStore ( gvsmirnov ), (, ) , .
ããã¯ããªããžã§ã¯ãã®å®å
šã§ãªãå
¬éã«å¿
èŠã§ãïŒã³ãŒãã«ãšã©ãŒãããããªããžã§ã¯ããã¬ãŒã¹ãéããŠå
¬éãããŠããå Žåããã£ãŒã«ãã®ããã©ã«ãå€ãŸãã¯ã³ã³ã¹ãã©ã¯ã¿ãŒãåºåãããã®ã衚瀺ããããšãæåŸ
ããŸãïŒèšèªä»æ§ã¯ãããä¿èšŒããŸãïŒ ããããèæ°å³æªãããã§ã¯ãªããä»®æ³ãã·ã³ã¯æ£ããããããŒãèŠãããšãæåŸ
ããŠããŸããx86ã«ã¯åŒ·åãªã¡ã¢ãªã¢ãã«ãããããã®åœä»€ã¯å¿
èŠãããŸããããã®ãããARMãæ€èšããŸããã
å®è·µçã«ãã§ãã¯
äžèšã®ã³ãŒãã®ãã°ã«æ³šæããŠãã ãããç§ã¯ãããæ£ããããšã蚌æããã ãã§ã詊ããããšã¯ãããŸããã
ãããŸã§ã®ãšããããã¹ãŠãçŽ æŽãããèŠããŸãããœãŒã¹ã§ååã«å¹žéã§ãããããã€ãã®é¢çœãç¬éãçºèŠããŸããããã³ã³ãã€ã©ãå®éã«äœãããã®ãåãããªããããããŸãããPrintAssembly
new Long(1023)
:
0x0000000105eb7b3e: mov 0x60(%r15),%rax 0x0000000105eb7b42: mov %rax,%r10 0x0000000105eb7b45: add $0x18,%r10 ; 24 : 8 , ; 4 , ; 4 , ; 8 long 0x0000000105eb7b49: cmp 0x70(%r15),%r10 0x0000000105eb7b4d: jae 0x0000000105eb7bb5 0x0000000105eb7b4f: mov %r10,0x60(%r15) 0x0000000105eb7b53: prefetchnta 0xc0(%r10) ; prefetch 0x0000000105eb7b5b: movq $0x1,(%rax) ; 0x0000000105eb7b62: movl $0xf80022ab,0x8(%rax) ; Long 0x0000000105eb7b69: mov %r12d,0xc(%rax) 0x0000000105eb7b6d: movq $0x3ff,0x10(%rax) ; 1023
, , .
, :
- TLAB'.
- TLAB' , eden' TLAB, eden', .
- eden' , .
- , .
- , OOM.
- .
: , prefetch TLAB' -.
å®éš
, , . , java.lang.Object
, JVM.
Java 1.8.0_121, Debian 3.16, Intel Xeon X5675. â , â .

:
- , ,
new
. , : - (, Blackhole#consumeCPU
), , . - prefetch . JVM , -, . , .
- TLAB' : â JIT -> JVM, , .
finalize
, eden' finalizable-:

!
ãããã«
JVMã¯ãæ°ãããªããžã§ã¯ããã§ããéãè¿
éãã€ç°¡åã«äœæããããã«å€ãã®ããšãè¡ããTLABãæäŸããäž»èŠãªã¡ã«ããºã ã§ããTLABèªäœã¯ãã¬ããŒãžã³ã¬ã¯ã¿ãšã®ç·å¯ãªååã®ãããã§ã®ã¿å¯èœã«ãªããŸãããã¡ã¢ãªãè§£æŸãã責任ãããã«ç§»ããŠãå²ãåœãŠã¯ã»ãšãã©èªç±ã«ãªããŸããã
ãã®ç¥èã¯é©çšå¯èœã§ããïŒãã¶ãããšã«ãããã©ã®ãããªå Žåã§ããæ¥œåšãã©ã®ããã«å
éšã«é
眮ãããã©ã®ãããªã¢ã€ãã¢ã䜿çšããŠããããçè§£ããããšã¯åžžã«åœ¹ã«ç«ã¡ãŸãã
ã¬ãã¥ãŒã®ããã«apanginãšgvsmirnovã«æè¬ããŸãããããªãã§ã¯ããããŸããªèšèé£ããã³ãŒãã®ãªã¹ãããããã§æºããããèšäºã®çãäžã«å°éããåã«éå±ã§æ»ãã§ããŸããŸãã