从 memory leaks 的思考 -- 如何避免内存 ( 资源 ) 泄漏

84 阅读1分钟

今天早上小伙伴反馈某个服务调用超时率比较明显,对应的服务发现出现 ClientAbortException,检查监控惊讶发现有好几个 POD 的内存使用率已经顶天了: image.png 查看其中的一个 POD GC: image.png

从上面的图来看内存泄漏无疑了,这个时候 heap dump + MAT 就出场了。

2000 years later······

在经历了漫长的 dump & transport,打开 hprof 文件,问题一眼就映入眼中: image.png

TsrReplayUtilchainIdMap( ConcurrentHashMap ) 消耗了 90+%的内存!!!!!接着进一步展开: image.png 可以得到:1. map ( 集合 ) 没有设置上限;2. value ( 集合中的集合 ) 没有设置上限。

那我们能有什么做的?

  1. 限制资源使用上限,特别是容易忽略的集合中集合,这在诸如中间件中非常常见 ( 如在某些 LB 中,正是因为 http header 超过设定大小返回 409 );
  2. 使用 SoftReference & WeakReference,哪怕疏忽忘记限制资源仍然不会有过多影响 ( 同样对于我们常用的 Google Guava Cache,可以通过 CacheBuilder.newBuilder().softValues()合理使用 )。