SolrCloud 集群 ConcurrentLRUCache Full Gc 问题查找 即 JVM老年代无法回收

1.问题描述


jstat -gcutil   25477  1000

SolrCloud 集群 ConcurrentLRUCache Full Gc 问题查找 即 JVM老年代无法回收_第1张图片

Solr  JVM ,一直FUll  GC,老年代对象一直存活,无法回收,初步分析: 使用 eclipse 插件  Memory  Analysis Tools ( MAT )分析老年代 内存占用情况

2.  进行步骤

       A.导出  内存快照

        jmap -dump:format=b,file=/tmp/heap.hprof  25477

        

     B.把  /tmp/heap.hprof  下载到本地,使用  MAT 进行分析

3.结果分析

SolrCloud 集群 ConcurrentLRUCache Full Gc 问题查找 即 JVM老年代无法回收_第2张图片

SolrCloud 集群 ConcurrentLRUCache Full Gc 问题查找 即 JVM老年代无法回收_第3张图片



    从图中可以看出,org.apache.solr.util.ConcurrentLRUCache  对象竟然使用  10.8G的堆内存空间。


      两个 ConcurrentLRUCache  对象 object  占用 20G的内存,堆内存 一共30G,这是内存无法接受。

4.问题解决及理论

      A. Lucene 有两种缓存   FieldCache   和 Filter Cache ,Solr 在lucene 又增加 queryResult、DocumentCache 和  perSegFilter (自定义缓存) ,一份  solr  JVM索引 对应的缓存 value ,都存放在 ConcurrentLRUCache 的   private final ConcurrentHashMap> map 里。

           解决方案:

修改响应的size 的大小,观察几天JVM 内存使用情况




SolrCloud 集群 ConcurrentLRUCache Full Gc 问题查找 即 JVM老年代无法回收_第4张图片

问题延伸:

             1.此问题是由于缓存无法回收引起的,用过改天缓存大小解决

             2.解决办法二: 增加弱引用的使用,使用 WeakHashMap  来存放缓存对象,及时清理缓存对象。

             3. solr 内存会在索引预热阶段,清理缓存,当我们基于 lucene 做二次开发建立集群的时候,可以在预热阶段,自行清理WeakHashMap  缓存对象。

你可能感兴趣的:(JVM)