public void mytest() { long start = System.currentTimeMillis(); Thread thread = Thread.currentThread(); Field threadLocalsField = null; try { threadLocalsField = Thread.class.getDeclaredField("threadLocals"); threadLocalsField.setAccessible(true); Class threadLocalMapKlazz = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); Field tableField = threadLocalMapKlazz.getDeclaredField("table"); tableField.setAccessible(true); Object table = tableField.get(threadLocalsField.get(thread)); int threadLocalCount = Array.getLength(table); StringBuilder sb = new StringBuilder(); StringBuilder classSb = new StringBuilder(); int leakCount = 0; for (int i = 0; i < threadLocalCount; i++) { Object entry = Array.get(table, i); if (entry != null) { Field valueField = entry.getClass().getDeclaredField("value"); valueField.setAccessible(true); Object value = valueField.get(entry); if (value != null) { classSb.append(value.getClass().getName()).append(", "); } else { classSb.append("null, "); } leakCount++; } } sb.append("possible ThreadLocal leaks: ") .append(leakCount) .append(" of ") .append(threadLocalCount) .append(" = [") .append(classSb.substring(0, classSb.length() - 2)) .append("] "); log.warn(sb.toString()); } catch (Exception e) { e.printStackTrace(); } long end = System.currentTimeMillis(); long cost = end - start; log.info("获取ThreadLocal耗时:{}", cost); 结果: possible ThreadLocal leaks: 9 of 16 = [java.util.Collections$SynchronizedMap, null, java.lang.Boolean, java.lang.Boolean, null, java.lang.Integer, java.lang.Boolean, brave.propagation.TraceContext, null]
原文地址:https://www.cnblogs.com/zhangzhi19861216/p/12152973.html
时间: 2024-08-01 00:14:18