场景:
有一个项目运行一段时间后就会出现OOM,下面梳理下寻找问题根源的方法
问题重现
某一天,一个好久没动过的服务崩掉了,top查看进程占用CPU高达700%+ ???? 按照top,jstack一条龙查找导致异常的线程
这里没看到什么异常,把堆文件dump到本地进行分析:
???? 看到HashMap将近占了内存大小的50%。开始寻找项目里哪里用到HashMap
项目里没有找到使用HashMap的地方,转而思考是否是引用的第三方工具包使用不当导致OOM
看到有很多set方法和map方法,最后想到这部分应该是Orika中实体转化过程中反射部分用到的。大体确定是Orika导致的问题,于是查看项目中使用到Orika的地方
发现每次使用Orika转化对象时,都会去register一次。。。实际上可以只针对字段有差异的对象进行映射并注册一次,其他相同字段的对象可以选择默认映射。
至此问题解决。
????♂ 小插曲: 在查找问题过程中看到HashMap可能会导致内存泄漏的原因,这边也总结下,主要是因为hashMap的key可能是一个自定义对象,而这个对象的hashCode和equals方法可能是有问题的。因为HashMap在put一个新对象时,会通过key的hashCode方法和equals方法来确定是否发生hash冲突,进而新增或替换旧值,如果equals方法或hashCode方法是根据 变量 做计算并返回结果的话,可能会因为自定义对象的 变量变化 而导致hashCode方法或equals方法返回的值与原来的不一样,反反复复,就会有多个相同的value插入,但是却无法引用到。最终导致OOM
参考:https://www.jianshu.com/p/54c388e9bf3b