Log4j2:MDC踩坑记录之OutOfMemoryError
为了更好的追踪日志,我在项目里使用了Log4j2的MDC功能,大概的用法如下,这个用法是错误的
try {
logger.info("开始处理 task:{}", task);
ThreadContext.put("traceId", task.getKey());
//实际业务
}finally {
ThreadContext.remove("traceId");
}
我的理解MDC是基于ThreadLocal
实现的,所以用完后要remove
掉,上线后跑了一天一夜,结果OOM了。
因为最近没啥改动,就是上了这个功能,所以第一印象就是加了MDC导致的内存溢出。
用 jmap -histo [pid]
****看了一下内存情况,没有特别异常的类,只是[C
占用的内存特别高,基本可以肯定就是ThreadContext
的字符串没有释放掉导致的问题。
直接看ThreadContext源码,源码上有文档地址,https://logging.apache.org/log4j/2.x/manual/thread-context.html
官方文档提供了两个例子
1.使用CloseableThreadContext
,它里面的Instance
继承了AutoCloseable
,会在结束时,自动关闭清理
@Override
public void close() {
closeStack();
closeMap();
}
2.在使用结束后调用ThreadContext.clear();
方法进行删除
在代码中是找不到.clear()方法的,但是有些类似的方法,比如clearStack(),clearMap(),clearAll()
如果没有特殊要求,直接调用clearAll()就行
public static void clearAll() {
clearMap();
clearStack();
}
最后代码改成
try {
logger.info("开始处理 task:{}", task);
ThreadContext.put("traceId", task.getKey());
//实际业务
}finally {
ThreadContext.clearAll();
}
一点毛病都没有啊,老铁们!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗