WebLogic Server 12.2.1ã®ThreadLocal Clean Outæ©è½ãæ¤è¨¼ãã¦ã¿ã #javaee #jpoug
æ¬æ¥ã¯Java EE Advent Calendarã¨JPOUG Advent Calndarã®12æ¥ç®ã§ãã*1
WebLogic Server(以éãWLS) 12.2.1ã先日10/26にリリースããã¾ããã
ããã¯ã12c Release 2(12cR2)ã§ãããããã3å¹´ã¶ãã®ã¡ã¸ã£ã¼ãã¼ã¸ã§ã³ã¢ããã®ä½ç½®ä»ãã¨ãªã£ã¦ãã¾ãã
ç®çã¨ãªãæ°æ©è½ã¨ãã¦ã¯ä»¥ä¸ããããå
¬å¼ãããæ§ã
ãªæ
å ±ãé 次åºã¦ãã¦ãã¾ãã
ããã§ã¯ãç´°ããã§ããçãæã«æãå±ãæ°æ©è½ã¨ãã¦ãThreadLocal Clean Outãç´¹ä»ã»æ¤è¨¼ãã¦ã¿ã¾ãã
ThreadLocalã¨ã¯ã©ã¹ãã¼ããªã¼ã¯ã®ãããã
ã¾ããWLSã«éããJavaã¢ããªã±ã¼ã·ã§ã³ãµã¼ãå
¨è¬ã¨ãã¦ãThreadLocalå©ç¨æã®æ³¨æç¹ã一昨年のAdvent Calendarã«ã¦è¨äºãæ¸ãã¾ããã
åºæ¬çã«ã¯ThreadLocalã使ã£ãå ´åã¯ã確å®ã«ç ´æ£ããªãã¨ã¯ã©ã¹ãã¼ããªã¼ã¯ã®åå ã«ãªãã¾ãã*3
ã¾ããè¨äºã«ãå°ã
è¨è¼ãã¦ãã¾ããããå½æTomcatã§ã¯ThreadLocalã®èªååé¤ã«å¯¾å¿ãã¦ãããWLSã§ãåæ§ã®æ©è½ãããã¨ãããªã¨æã£ã¦ããã®ã§*4ãWLS 12.2.1ããã®æ°æ©è½ã¨ãã¦å®è£
ãããã®ã¯ããã®ã¨ãã®æè¦ãåæ ãããããã«ãæããå¬ããã¨ããã§ãã
ThreadLocalã使ã£ããµã³ãã«ã¢ããªã±ã¼ã·ã§ã³
ThreadLocalã¯ãã¬ã¼ã ã¯ã¼ã¯ãã©ã¤ãã©ãªå
ã§å©ç¨ããããã¨ãå¤ãã¨æ³å®ããããã®å ´åã¯ç¢ºå®ã«ç ´æ£ããããç ´æ£ã¡ã½ãããå¥éå¼ã³åºããããªã¬ã¤ãã©ã¤ã³ãããã§ãããã
ããã§ã¯ã¹ã¬ããã»ã¼ãã§ãªãã¦ãç¾å ´ã§ãã©ãã«ãèµ·ããããªä»£è¡¨æ ¼ã®ä¸ã¤*5ã§ããSimpleDateFormatã使ã£ãå®è£
ãèãã¦ã¿ã¾ãã
ãã¡ãããJDK 8ããã¯Date and Time APIã®DateTimeFormatterãç¨æããã¦ãããã¹ã¬ããã»ã¼ããªã®ã§ããã使ãã¹ãã§ãããããã¬ã¬ã·ã¼ã ã£ããå®æãªå®è£ ã§ããã¨èãã¦ãã ããã
ã·ããªãª
SimpleDateFormatãç¶æ¿ããã¯ã©ã¹ãå©ç¨ãã¦ããããã¹ã¬ããã»ã¼ãã§ã¯ãªãããã¹ãæã«åé¡ãçºè¦ãã*6ããã«ãThreadLocalã使ã£ãå®è£
ã«åãæ¿ããã¨ããã·ããªãªã§èãã¦ã¿ã¾ãããã
以ä¸ã®ãããªãµã³ãã«ã¨ãã¦ã¿ã¾ããã*7
public class CustomDateFormat extends SimpleDateFormat { public CustomDateFormat() { super("yyyy-MM-dd HH:mm:ss.SSS"); } }
@ApplicationScoped @Path("now") public class NowResource { private static final ThreadLocal<DateFormat> DF_LOCAL = ThreadLocal.withInitial(() -> new CustomDateFormat()); @GET @Produces(MediaType.TEXT_PLAIN) public String getText() { DateFormat df = DF_LOCAL.get(); System.out.printf("Thread: %s%n", Thread.currentThread().getName()); System.out.printf("this identity=0x%x%n", System.identityHashCode(this)); System.out.printf("DF_LOCAL identity=0x%x%n", System.identityHashCode(DF_LOCAL)); System.out.printf("df identity=0x%x%n", System.identityHashCode(df)); System.out.println(); return df.format(new Date()); } }
ãµã³ãã«ã¢ããªã±ã¼ã·ã§ã³ã®èæ ®ç¹ã»æ³¨æç¹
ããã»ã©æ¬è³ªã§ã¯ãªãã®ã§ãé£ã°ãã¦ããã ãã¦æ§ãã¾ãããã念ã®ãã以ä¸ã«ã¤ãã¦ããçæã»ãäºæ¿ãã ããã
- package/importæã¯ãããã§ã¯çç¥ãã¦ãã¾ãã
- SimpleDateFormatãç¶æ¿ããåç´ãªCustomDateFormatã¯ã©ã¹ãããã¦ä½æãã¦ãã¾ãããã¢ããªã±ã¼ã·ã§ã³å
ã§å
±éåããæ¥ä»æ¸å¼ã使ãããã£ãã·ããªãªã¨ãç解ãã ããã
- SimpleDateFormatã¯ããã¼ãã¹ãã©ããã¯ã©ã¹ãã¼ãã«ã¦é常ã¯ãã¼ããããããããã®ã¾ã¾ã§ã¯ThreadLocalã«å ¥ãã¦ãã¯ã©ã¹ãã¼ããªã¼ã¯ã¯çºçããªãã¯ãã§ãã
- CustomDateFormatã¯ãJavaã¢ããªã±ã¼ã·ã§ã³ãµã¼ããå®è£ ãã¦ããWebã¢ããªã±ã¼ã·ã§ã³ç¨ã®ã¯ã©ã¹ãã¼ã(WLSã§ã¯weblogic.utils.classloaders.ChangeAwareClassLoader)ã«ã¦ãã¼ããããã¯ã©ã¹ã¨ãã¦ãã¾ãã
- NowResourceã¯JAX-RSã®ãªã½ã¼ã¹ã¯ã©ã¹ã¨ãã¦ãããé½åº¦ã¤ã³ã¹ã¿ã³ã¹åãããå¿
è¦ããªããããCDIã®@ApplicationScopedãçµã¿åããã¦ãã¾ãã
- javax.ws.rs.core.Applicationãç¶æ¿ããã¯ã©ã¹ãå¿ è¦ã§ãããããã§ã¯çç¥ãã¦ãã¾ãã
- @ApplicationScopedã§ãããããThreadLocalã®å®£è¨ã¯staticã§ãªãã¦ãããã§ãããã¹ã¬ããã«ç´ä»ãã¦ç®¡çãããããstaticã§å®ç¾©ãããã¨ãæ¯è¼çå¤ããã¨æãã¾ãã
- JDK 8ããå°å ¥ãããThreadLocal.withInitialã使ã£ã¦å¾®å¦ã«ã©ã ãå¼ã使ã£ã¦ãã¾ãããããã»ã©æå³ã¯ããã¾ãããå¾è¿°ãã¾ãããå¾æ¥ããå©ç¨ãã¦ããã§ãããinitialValue()ããªã¼ãã¼ã©ã¤ããã¦ãããã§ãããã
- System.outã¯æ¬çªç¨ã¢ããªã±ã¼ã·ã§ã³ã§ã¯ä½¿ãã¹ãã§ã¯ãªãã§ãããããã¾ã§ãããã°ç®çã®æ¤è¨¼ç¨ã»ãµã³ãã«ã¨ãããã¨ã§ãç解ãã ããã
å®è¡ãã¦ã¿ã
ä¸è¨ã®ãµã³ãã«ã¢ããªã±ã¼ã·ã§ã³ãWLS 12.2.1ã«ãããã¤ããå®è¡ãã¦ã¿ã¾ãããã
ãã©ã¦ã¶ãä»»æã®HTTPã¯ã©ã¤ã¢ã³ãã§ãhttp://host:port/context-root/application-path/nowãã«ã¢ã¯ã»ã¹ãã¦ã¿ã¦ãã ããã*8
ä½åº¦ãå®è¡ããã¨ã以ä¸ã®ãããªå½¢ã§æ¨æºåºåã«åºåããã¾ããã
Thread: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x52097801 DF_LOCAL identity=0x5bc771ce df identity=0x2f93ea4c Thread: [ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x52097801 DF_LOCAL identity=0x5bc771ce df identity=0x7b243b31 Thread: [ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x52097801 DF_LOCAL identity=0x5bc771ce df identity=0x7b243b31 Thread: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x52097801 DF_LOCAL identity=0x5bc771ce df identity=0x2f93ea4c
thisãDF_LOCALã¯ãå½ããåã§ããä½åº¦å®è¡ãã¦ããªãã¸ã§ã¯ãIDã«å¤åã¯ããã¾ããã
dfã®ã¨ããã«æ³¨ç®ããã¨ãWLSã®å®è¡ã¹ã¬ãã(ä¸è¨ã§ããã°ExecuteThread: '0'ã¨'2')ãã¨ã«ãªãã¸ã§ã¯ãIDãç°ãªãã®ã確èªã§ãã¾ãã
è¨ãæããã¨åãã¹ã¬ããã§ããã°ãCustomDateFormatãåå©ç¨ããã¦ããã®ãåããã¾ãã
- ExecuteThread: '0' â 0x2f93ea4c
- ExecuteThread: '2' â 0x5bc771ce
ããã§ãã§ãããã§ããï¼ã¨ãã訳ã«ã¯æ®å¿µãªããè¡ãã¾ããã
ThreadLocal#remove()ãå¼ã³åºãç®æããªããããåãããã¤ãããã¨ã§ãåºæ¬çã«ã¯ã©ã¹ãã¼ããªã¼ã¯ã«ã¤ãªããã¯ãã§ãã
EagerThreadLocalCleanupãæå¹ã«ãã
ããããæ¬é¡ã®ã¨ããã«å ¥ã£ã¦ããã¾ããããThreadLocal Clean Outのドキュメントã確èªããã¨ãKernelMBeanã«eagerThreadLocalCleanupå±æ§ãããããããæå¹åããã°æ©è½ãããã§ãã
To clean up stray ThreadLocal use by applications and third-party libraries, configure the eagerThreadLocalCleanup attribute in the KernelMBean. The eagerThreadLocalCleanup attribute specifies whether to clean up all ThreadLocal storage from self-tuning thread pools after they have finished processing each work request.
æ©éæå¹åãã¦ã¿ããã¨ããã§ããã管çã³ã³ã½ã¼ã«ã«ã¯ãããããè¨å®ã¯è¦å½ããã¾ããããããªã¨ãã¯WLST(WebLogic Scripting Tool)ã使ãã®ãå®ç³ã§ããWLSTã®ä½¿ãæ¹ã¯ããã§ã¯èª¬æãã¾ããã®ã§ãWLSåå¼·ä¼ã®è³æã使ってみよう WLSTããªã©ãåç §ãã¦ãã ããã
ã¾ããconnectã³ãã³ãã§æ¥ç¶ãã¦ãfindã³ãã³ãã§å±æ§ãã©ãã«å®ç¾©ããã¦ããããæ¢ãã¦ã¿ã¾ãããã
wls:/offline> connect('weblogic','welcome1') ã¦ã¼ã¶ã¼ID weblogicã§t3://localhost:7001ã«æ¥ç¶ãã¦ãã¾ã ... ãã¡ã¤ã³"base_domain"ã«å±ãã管çãµã¼ãã¼"AdminServer"ã«ããæ£å¸¸ã«æ¥ç¶ããã¾ãã è¦å: ãµã¼ãã¼ã¸ã®æ¥ç¶ã«å®å ¨ã§ãªããããã³ã«ã使ç¨ããã¾ããã éä¿¡ã»ãã¥ãªãã£ã確ä¿ããã«ã¯ããããã«SSLãã¼ãã¾ãã¯ç®¡çãã¼ãã使ç¨ããå¿ è¦ãããã¾ãã wls:/base_domain/serverConfig/> find('threadlocal') ãã¹ã¦ã®ç»é²æ¸MBeanã¤ã³ã¹ã¿ã³ã¹ã§"threadlocal"ãæ¤ç´¢ãã¦ãã¾ã... /Servers/AdminServer EagerThreadLocalCleanup false
ããã§ã¯AdminServerã«å®ç¾©ããã¦ãããã¨ãåããã¾ãããè¤æ°ã®WLSã¤ã³ã¹ã¿ã³ã¹ãããã°ãããããè¨å®ãããã¨ã«ãªãã¾ãã
ãªããããã¥ã¡ã³ãã§ã¯KernelMBeanã«eagerThreadLocalCleanupå±æ§ããããã¨ã«ãªã£ã¦ãã¾ãããåã
ã®WLSã¤ã³ã¹ã¿ã³ã¹ã¯ServerMBeanã¨ãã¦åç
§ã»è¨å®ãã¾ããããã¦ãServerMBeanã¯KernelMBeanãç¶æ¿ãã¦ãããã¨ããMBeanリファレンスãAPIドキュメントãããåããã¾ãã
ããã§ã¯EagerThreadLocalCleanupãæå¹åãã¦ã¿ã¾ããããè¨å®å¤æ´å¾ã«WLSã®åèµ·åãå¿ è¦ã¨ãªãã¾ãã
wls:/base_domain/serverConfig/> edit() wls:/base_domain/edit/> startEdit() ç·¨éã»ãã·ã§ã³ãéå§ãã¦ãã¾ã ... ç·¨éã»ãã·ã§ã³ãéå§ããã¾ãããå¤æ´ãå®äºããããå¿ ãä¿åãã¦ã¢ã¯ãã£ãåãã¦ãã ããã wls:/base_domain/edit/ !> cd('/Servers/AdminServer') wls:/base_domain/edit/Servers/AdminServer !> cmo.setEagerThreadLocalCleanup(true) wls:/base_domain/edit/Servers/AdminServer !> save() ãã¹ã¦ã®å¤æ´ãä¿åãã¦ãã¾ã ... ãã¹ã¦ã®å¤æ´ãæ£å¸¸ã«ä¿åããã¾ããã wls:/base_domain/edit/Servers/AdminServer !> validate() å¤æ´ãæ¤è¨¼ãã¦ãã¾ã ... å¤æ´ãæ£å¸¸ã«æ¤è¨¼ããã¾ãã wls:/base_domain/edit/Servers/AdminServer !> showChanges() ã¢ã¯ãã£ãåããã¦ããªããã¹ã¦ã®å¤æ´: å¤æ´ãããMBean: com.bea:Name=AdminServer,Type=Server å¼ã³åºãããæä½: modify å¤æ´ãããå±æ§: EagerThreadLocalCleanup å±æ§ã®å¤ãå¤: false å±æ§ã®æ°ããå¤: true ãµã¼ãã¼ã®åèµ·åãå¿ è¦: true wls:/base_domain/edit/Servers/AdminServer !> activate() ãã¹ã¦ã®å¤æ´ãã¢ã¯ãã£ãåãã¦ãã¾ãããã°ããæéããããå ´åãããã¾ã ... ã¢ã¯ãã£ãåãå®äºããã¨ããã®ç·¨éã»ãã·ã§ã³ã«é¢é£ä»ããããç·¨éããã¯ãéæ¾ããã¾ãã MBeanã§æ¬¡ã®éçå±æ§ãå¤æ´ãããããã serverã®åèµ·åãå¿ è¦ã§ãã å¤æ´ãããMBean: com.bea:Name=AdminServer,Type=Server å¤æ´ãããå±æ§: EagerThreadLocalCleanup ã¢ã¯ãã£ãåãå®äºãã¾ãã
å度å®è¡ãã¦ã¿ã
WLSã®åèµ·åãå®äºããããåã³ã¢ããªã±ã¼ã·ã§ã³ãä½åº¦ãå®è¡ãã¦ã¿ã¾ãããã
以ä¸ã®ãããªåºåã確èªã§ãã¾ãã
Thread: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x142db2b2 DF_LOCAL identity=0x7b62b3d4 df identity=0x78301aea Thread: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x142db2b2 DF_LOCAL identity=0x7b62b3d4 df identity=0x25cba42c Thread: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x142db2b2 DF_LOCAL identity=0x7b62b3d4 df identity=0x58d69058 Thread: [ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x142db2b2 DF_LOCAL identity=0x7b62b3d4 df identity=0x38578023
thisã¨DF_LOCALã¯ã(ãã¡ããå½ããåã§ãã)å
ã»ã©ã¨åæ§ã«ä½åº¦å®è¡ãã¦ããªãã¸ã§ã¯ãIDã«å¤åã¯ããã¾ããã
ããããdfã¯åãå®è¡ã¹ã¬ãã(ããã§ã¯ã"ExecuteThread: '0'")ã§ããæ¯åãªãã¸ã§ã¯ãIDãç°ãªã£ã¦ããããªã¯ã¨ã¹ãã®é½åº¦ãªãã¸ã§ã¯ããåä½æããã¦ãããã¤ã¾ãThreadLocalé åãç ´æ£ããã¦ãããã¨ã窺ãã¾ãã
çæã»ç ´æ£ã®åä½ã確èªãã
å
ã®ãµã³ãã«ã¢ããªã±ã¼ã·ã§ã³ã®ThreadLocal
private static final ThreadLocal<DateFormat> DF_LOCAL = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { System.out.println("Initialized!"); return new CustomDateFormat(); } @Override public void remove() { super.remove(); System.out.println("Removed!!"); } };
ããã§ãã«ãã»ãããã¤ããå度ã¢ããªã±ã¼ã·ã§ã³ãä½åº¦ãå®è¡ããã¨ä»¥ä¸ã®ããã«ãªãã¾ããã
Initialized! Thread: [ACTIVE] ExecuteThread: '4' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x4276fc09 DF_LOCAL identity=0x771e79d2 df identity=0x49683253 Initialized! Thread: [ACTIVE] ExecuteThread: '4' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x4276fc09 DF_LOCAL identity=0x771e79d2 df identity=0x387e8df1 Initialized! Thread: [ACTIVE] ExecuteThread: '4' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x4276fc09 DF_LOCAL identity=0x771e79d2 df identity=0x5c5ffe39 Initialized! Thread: [ACTIVE] ExecuteThread: '4' for queue: 'weblogic.kernel.Default (self-tuning)' this identity=0x4276fc09 DF_LOCAL identity=0x771e79d2 df identity=0x43972404
ãã®çµæãããinitialValue()ã¯ãªã¯ã¨ã¹ãã®é½åº¦å¼ã°ãã¦ãããããåä½æããã¦ãããã¨ã¯åããã¾ãããremove()ã«ããæ示çãªç ´æ£ãè¡ããã¦ãã¾ããã
WLSã¯ãªã¼ãã³ã½ã¼ã¹ã§ã¯ãªããããã©ã®ãããªå®è£
ã¨ãªã£ã¦ãããåããã¾ããããEagerThreadLocalCleanupå±æ§ãæå¹åãã¦ããThreadLocal#remove()ãå¼ã³ã ãã®ã§ã¯ãªããå¥ã®æ¹æ³ã使ã£ã¦å®è¡ã¹ã¬ããã®ThreadLocalé åãç ´æ£ãã¦ããããã§ãã
remove()ãå¼ã°ããªãã¦ãã以åã«ThreadLocalã«ç´ä»ãã¦ãããªãã¸ã§ã¯ãã¯åç
§ããå¤ããé常ã¯GC対象ã¨ãªããããåé¡ã«ãªãã±ã¼ã¹ã¯å°ãªãã§ãããã
ThreadLocalã«å¤é¨ãªã½ã¼ã¹ã管çããã¯ã©ã¹*10ãç´ã¥ããããªå®è£
ããã¦ããå ´åã¯ã注æãå¿
è¦ããããã¾ããããã£ã¨ãããã®å ´åã¯èªååé¤ã«é ¼ãã®ã§ã¯ãªããã¢ããªã±ã¼ã·ã§ã³ã§æ示çã«ThreadLocal#remove()ãå¼ã°ãªãã¨ããªã½ã¼ã¹ãæ¯æ¸ãã¦åé¡ã«ãªãã±ã¼ã¹ãå¤ãã¯ãã§ãã
èå¯ãã¦ã¿ã
ä¸è¨ã¾ã§ã®åä½ãããEagerThreadLocalCleanupã®è¨å®ã常ã«æå¹ã«ããã»ããããã®ã§ããããï¼
ä»åã®ãµã³ãã«ã¢ããªã±ã¼ã·ã§ã³ã®ä¾ã§ã¯ãDateFormatãªãã¸ã§ã¯ãããã£ãã·ã¥ãã¦å¹ççã«æ±ãããã«ThreadLocalã«ç´ä»ãã¦ãã¾ããããªã¯ã¨ã¹ãã®é½åº¦ããªãã¸ã§ã¯ããåçæããã¦ãã¾ãã®ã§ã¯ãThreadLocalãå©ç¨ãã¦ã¹ã¬ããã»ã¼ãã«æ±ãããã工夫ããæå³ããªããªã£ã¦ãã¾ãã¾ãã
ã¨ã¯ãããã¤ã³ãã©è¦³ç¹ã§ã¯ãåãããã¤æã«ã¯ã©ã¹ãã¼ããªã¼ã¯ãçºçãã¦ãã¾ã£ã¦ã¯ãé·æéå®å®çã«éç¨ã§ãããåèµ·åã«ããéç¨ã®è² è·ãä¸ãã£ã¦ãã¾ãã®ã§ã¯ãªããâ¦â¦
ãå®å¿ãã ãããWLS 12.2.1ã®ThreadLocal Clean Outのドキュメントã«ã¯ç¶ããããã¾ãã
By default, the eagerThreadLocalCleanup attribute is set to false, in which the self-tuning thread pool only cleans up ThreadLocal storage when a thread returns to a standby pool and after an application is undeployed.
Setting the eagerThreadLocalCleanup attribute to true ensures that all thread pool threads have no leftover ThreadLocal values from previous requests when running work for a new request. However, overhead occurs from cleaning up ThreadLocal storage after each work request and then reestablishing ThreadLocal values for each new request. Since some applications cache objects that are expensive to create in the ThreadLocal storage, cleaning up ThreadLocal values after each request may negatively impact performance on those applications.
ã¤ã¾ããEagerThreadLocalCleanupãããã©ã«ãã®ç¡å¹ã®ã¾ã¾ã§ãã£ã¦ããã¢ã³ãããã¤å¾ã«ã¯ThreadLocalé åã¯ç ´æ£ãããã¨ã®ãã¨ã§ãã
ã¾ããEagerThreadLocalCleanupãæå¹ã«ãã¦ããã¨ããªã¯ã¨ã¹ãã®é½åº¦ã«ThreadLocalé åãç ´æ£ãããã®ã§ãã¢ããªã±ã¼ã·ã§ã³ã«ãã£ã¦ã¯ããã©ã¼ãã³ã¹ã«æªå½±é¿ãä¸ããå¯è½æ§ã«ã¤ãã¦ãè¨åããã¦ãã¾ãã
ã¯ã©ã¹ãã¼ããªã¼ã¯ãæ¤è¨¼ãã¦ã¿ã
ã§ã¯ã念ã®ãããåãã¢ããªã±ã¼ã·ã§ã³ãWLS 12.1.3/WLS 12.2.1ã§ä½åº¦ãåãããã¤ã»å®è¡ãã¦ããã¼ããã³ããè¦ã¦ã¿ã¾ããããããã§ã¯VisualVMã使ã£ã¦ã¿ããã¨ã«ãã¾ãã*11
ããå°ãè£è¶³
Tomcatã®ThreadLocalèªååé¤æ©è½ã¯ãアンデプロイ時にスレッドプールを破棄するã¨ãããåã°åæçãªå®è£
ã«ãè¦åãããã¾ãã
ããã¨æ¯è¼ãã¦ãWLS 12.2.1ã®ThreadLocal Clean Outã¯ããã®è¨äºãæ¸ãã«ããã£ã¦èª¿ã¹ã¦ã¿ãéãã§ã¯ãã³ã¢æ©è½ã§ããå®è¡ã¹ã¬ãããã¼ã«ãæ´»ãããã¾ã¾ãThreadLocalé åãç ´æ£ãã¦ãããã®ã§ãããªãå®éç¨ã«èããããæãããã¾ãã
ãã ããã¯ã©ã¹ãã¼ããªã¼ã¯ã¯ThreadLocalã ããåå ã§ã¯ããã¾ããã
JDK 8以éã§ã¯Permanenté åããªããªãã代ããã«ãã¤ãã£ãé åã«Metaspaceã¨ãã¦ç¢ºä¿ããããã¨ã«ãªãã¾ããããããã©ã«ãã§ã¯Metaspaceã®æ大ãµã¤ãºã¯ãã»ã¼ç¡å¶éã¨ãªã£ã¦ãã¾ãã*12
ThreadLocal以å¤ã®ãªã¼ã¯ãèãããã¾ãã®ã§ãéç¨æã¯Metaspaceの領域を監視ãããã-XX:MaxMetaspaceSizeãªãã·ã§ã³ãå©ç¨ãã¦ãMetaspaceé åã®ãµã¤ãºãå¶éããã»ãããããã»ã¹ã®è¥å¤§åé²æ¢ã«ã¤ãªããã®ã§å®å
¨ã§ãããã
ã¾ã¨ã
ããã§ã¯ãã¾ã¨ãã§ãã
- WLS 12.2.1ã¯ThreadLocal Clean Outæ©è½ããããã¢ããªã±ã¼ã·ã§ã³ã§ThreadLocalãç ´æ£ãå¿ãã¦ããã¯ã©ã¹ãã¼ããªã¼ã¯ãçºçããå¯è½æ§ãä½ããªãã¾ããã
- ãã®æ©è½ã¯ã»ã¨ãã©ã®å ´åãæå¹ã«åä½ããã¯ãã§ãããããã«é ¼ããã¨ãªããThreadLocal#remove()ãæ示çã«å¼ã³åºããæ¹ãå®å ¨ã§ãããã
- ThreadLocal以å¤ãåå ã§ãã¯ã©ã¹ãã¼ããªã¼ã¯ãçºçããå¯è½æ§ã¯ããã¾ãã®ã§ãPermanent/Metaspaceé åã®ãµã¤ãºãç£è¦ã»å¶éãããã¨ãæ¤è¨ãã¾ãããã
*1:ã©ã¡ãã被ãã¦ãã¾ãã¾ãããã許ããã ããâ¦
*2:åãªãªã¼ã¹ã§ããWLS 12.1.3ã§ãé¨åçã«Java EE 7ã«å¯¾å¿ãã¦ãã¾ãã
*3:ãã®å¾ã«ãid:n_agetsumaããã«ãã記事ã第十回 #渋谷javaでの資料ãåºã¦ãé常ã«åãããããã§ã
*4:ããã¯ããã§id:nekopããããツッコミが入ったりしていた
*5:ã¹ã¬ããã»ã¼ãã§ãªãã¦ç¾å ´ã§ãã©ãã«ãçºçããä»£è¡¨æ ¼ã®æ¬ä¸¸ã¯java.util.HashMapã§ãããâ¦
*6:å®éã«ç§ãåããããªãã¨ãããããããã¨ãããã¾ãâ¦
*7:ç¡çç¢çæãããã®ã§ãããµã«ãªæãã©ããæºè¼ã ã¨æãã¾ããâ¦
*8:RESTful APIã¨ãã¦ã¯ãç¾å¨ã®æ¥æãè¿ãã ãã§ãã®ã§ãç¹ã«é¢ç½ãã¨ããã¯ããã¾ããâ¦
*9:æ¬è³ªã«é¢ä¿ãªãã®ã§ãããå¿åå é¨ã¯ã©ã¹ã ã¨ãã¤ã¤ã¢ã³ãæ¼ç®åã使ããªãã®ãä»æ´ç¥ãã¾ããâ¦
*10:ãã¡ã¤ã«ãDBã³ãã¯ã·ã§ã³ãªã©ãä¸è¬çã«æ示çãªclose()ã«ããç ´æ£ãããªãã¨ãªã½ã¼ã¹ãªã¼ã¯ãçºçãã
*11:å ã«ç´¹ä»ããn_agetsumaさんの記事ã§ã¯Eclipse Memory Analyzer(MAT)ã使ã£ã¦ããããã¡ãã®ã»ãã詳細ãªåæã¯ã§ããã¨æãã¾ã
*12:ãã®è¾ºãã®è©³ç´°ã¯ã末永さんの資料ãããJava8のHotSpotVMからPermanent領域が消えた理由とその影響ãã®è¨äºãåèã«ãªãã¾ã