太多份相同的对象导致 OOM

使用 WeakHashMap 不等于不会 OOM

Java 中引用类型和垃圾回收的关系:

  • 垃圾回收器不会回收有强引用的对象;
  • 在内存充足时,垃圾回收器不会回收具有软引用的对象;
  • 垃圾回收器只要扫描到了具有弱引用的对象就会回收,WeakHashMap 就是利用了这个特点。

Spring 提供的ConcurrentReferenceHashMap类可以使用弱引用、软引用做缓存,Key 和 Value 同时被软引用或弱引用包装,也能解决相互引用导致的数据不能释放问题。
与 WeakHashMap 相比,ConcurrentReferenceHashMap 不但性能更好,还可以确保线程安全。

Tomcat 参数配置不合理导致 OOM

总结思考

当我们需要动态执行一些表达式时,可以使用 Groovy 动态语言实现:new 出一个 GroovyShell 类,然后调用 evaluate 方法动态执行脚本。这种方式的问题是,会重复产生大量的类,增加 Metaspace 区的 GC 负担,有可能会引起 OOM。你知道如何避免这个问题吗?

groovy每次编译脚本,都会加载一个名字各不相同的类名,放在方法区,Class对象不可释放,随着次数的增加,编译的class对象将PERM区撑满

解决:思路是避免每次都evaluate脚本,而是把脚本转变为一个方法parse后缓存起来这个Script,以后直接invokeMethod来使用

groovy脚本导致的FullGC问题