网站建设好了怎么发布北京网络行业协会
2026/4/18 12:34:28 网站建设 项目流程
网站建设好了怎么发布,北京网络行业协会,免费ppt模板软件,网站开发信息前言继上次线上CPU出现了报警#xff0c;这次服务又开始整活了#xff0c;风平浪静了没几天#xff0c;看生产日志服务的运行的时候#xff0c;频繁的出现OutOfMemoryError#xff0c;就是我们俗称的OOM#xff0c;这可还行#xff01;频繁的OOM直接会造成服务处于一个不…前言继上次线上CPU出现了报警这次服务又开始整活了风平浪静了没几天看生产日志服务的运行的时候频繁的出现OutOfMemoryError就是我们俗称的OOM这可还行频繁的OOM直接会造成服务处于一个不可用的情况通过Skywalking查看链路调用基本全报红了基本处于一个瘫痪状态因为生产该服务是分布式部署运维当即立断对该服务进行重启因为是B端的产品先让公司业务能用起来了保证服务的正常使用然后紧急查看问题当然这个问题就来到了我这里既然分配给我了咱高低给它查出来并且修复了。OutOfMemoryError出现的原因先来了解下OutOfMemoryError出现的原因无非就是两类堆内存空间不足、元空间不足堆内存空间不足意味着程序存在一直有引用的对象强引用主要对象在引用的状态就无法被GC回收撑爆了-Xmx堆拓展的最大值内存不足自然就会触发堆内存溢出。元空间Java 8引入了元空间概念代替了之前堆的永久代由于元空间属于堆外内存不需要有对象引用通过指针的方式表示类和元数据之所以引用元空间就是一种JDK的升级优化避免了永久代的内存溢出。常见堆内存溢出的几种情况查询数据库返回的数据量过大加载到内存中导致内存溢出代码中出现死循环情况导致大对象一直被引用不能被GC回收资源链接池、io流在使用完没有进行手动释放静态集合类里面存在引用对象始终存在引用关系没有进行清除以上属于常见的几种堆内存溢出的场景当然有时候我们的遇到的问题都是稀奇古怪的问题常见的问题总是很少能遇到…现象分析根据生产环境的报错日志来看这边属于Mybatis报出的一个内存溢出情况通过去看Mybatis源码发现底层也是通过一些集合类来存放拼接的sql那么当然也有可能出现堆内存溢出而且在sql体积比较大的情况下接收sql的集合就会变的非常大如果回收不了那么就会导致内存溢出。由于我们docker容器里面没有一些jstack、jmap的工具并且dump文件也没有进行保存…导致我无法通过看线程高占用内存的对象来分析具体是什么操作发生的内存溢出这就难了… 于是只能去网上搜搜看了没想到真的给到我一些启发并且有点思路大概知道是哪里的问题。文章来源于zzzzbw作者写一篇关于 《惨遭DruidDataSource和Mybatis暗算,导致OOM》很感谢这位作者给我带来的启发。 文章作者也遇到了Mybatis带来的OOM主要是因为Mybatis拼接SQL的时候生成的占位符和参数对象存放在Map里当SQL的参数多导致SQL太长的时候Map持有这些SQL时间较长并且多线程同时操作这时候内存占用就很高从而发生OOMMybatis源码分析通过对DynamicContext类源码查看DynamicContext又一个ContextMap 类型的参数bindings继承了HashMap相当于一个Map集合接着看这个类中的getBindings方法看到了ForEachSqlNode这类调用了getBindings方法简单的说就是ForEachSqlNode通过getBindings方法将SQL参数和参数的占位符统一put到ContextMap这个集合里面主要是这里面的参数和占位符无法被GC回收并发查询量多的情况下就会导致OOM。情景复现随后我做了线上场景的复现通过将SQL语句的拼接将IN里面的参数变大然后创建50个线程进行执行将JVM堆内存设为-Xmx256m -XX:PrintGCDetails -XX:HeapDumpOnOutOfMemoryError这里看控制台打印的日志服务在频繁的进行Full GC导致OOM。总结既然发现了问题出现的原因接下来就是对代码SQL进行优化尽量避免在sql拼接的时候体积过大这里告诫我们代码不能乱写SQL语句也不能随意写啊有时候把问题想的过于简单确实会带来不可预知的风险。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询