内存泄露：是在为程序申请内存后，无法释放已申请的内存空间，一次内存泄露危害可以忽略，但内存泄露堆积后果很严重，无论多少内存,迟早会被占光，广义并通俗的说，就是：不再会被使用的对象或者变量占用的内存不能被回收，就是内存泄露。

使用场景：通常在数据库路由组件、基于Javaagent和字节码插桩的全链路监控组件中，都会有 ThreadLocal 以及增强的使用，用于记录同一个线程下之间调用，在最终的时候摘取调用链路上的信息。如：数据库路由设计会从 ThreadLocal 中获取分库分表信息。

泄漏原因：使用 ThreadLocal 但不在最后使用 ThreadLocal#remove 时，作为弱引用的 key 势必会在不调用时候被 GC 回收，这样就会导致 key 为 null，而 value 还存在着强引用。只有当线程完成退出后，强引用的链条才会断掉。否则链路 Thread Ref -> Thread -> ThreadLocalMap -> Entry -> value 永远无法回收，造成内存泄漏。 

一些知识：

1. 由于 Thread 中包含变量 ThreadLocalMap，因此 ThreadLocalMap 与 Thread 的生命周期是一样长，如果都没有手动删除对应key，都会导致内存泄漏。
2. 但是使用弱引用可以多一层保障：弱引用 ThreadLocal 不会内存泄漏，对应的 value 在下一次 ThreadLocalMap 调用set()、get()、remove()的时候会被清除，但如果有大量的线程操作一样有风险。
3. ThreadLocal 内存泄漏的根源是：由于 ThreadLocalMap 的生命周期跟 Thread 一样长，如果没有手动删除对应 key 就会导致内存泄漏，而不是因为弱引用。
4. 每次使用完 ThreadLocal 都调用它的 remove() 方法清除数据。
5. 将 ThreadLocal 变量定义成 private static，这样就一直存在 ThreadLocal 的强引用，也就能保证任何时候都能通过 ThreadLocal 的弱引用访问到 Entry 的 value 值，进而清除掉。