首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何配置Lucene (SOLR)内部缓存-内存问题/泄漏?

如何配置Lucene (SOLR)内部缓存-内存问题/泄漏?
EN

Stack Overflow用户
提问于 2014-01-16 13:25:20
回答 2查看 1.4K关注 0票数 2

我正在使用SOLR 4.4.0 -我发现(可能)与内部缓存机制有关的问题。JVM:-Xmx=15g,但是12g从来都不是免费的。我创建了堆转储,并使用MemoryAnyzer对其进行了分析--我发现2x6GB用作缓存数据。在第二次对-Xmx12g做同样的操作时,我发现1x3.5GB的缓存总是相同的。我签入了源代码,发现:

代码语言:javascript
复制
  /** Expert: The cache used internally by sorting and range query classes. */
  public static FieldCache DEFAULT = new FieldCacheImpl();

请参阅http://grepcode.com/file/repo1.maven.org/maven2/org.apache.lucene/lucene-core/4.4.0/org/apache/lucene/search/FieldCache.java#FieldCache.0DEFAULT

这是一个非常坏的消息,因为它是公共静态字段,在源代码中的大约160个地方使用。

MemoryAnalyzer说:

一个由"org.apache.catalina.loader.WebappClassLoader @ 0x58c3a9848“加载的”org.apache.catalina.loader.WebappClassLoader“实例占4,103,248,240字节(80.37%)字节。内存是在"java.util.HashMap$Entry[]“由"”加载的一个实例中积累的。 关键词java.util.HashMap$Entry[] org.apache.catalina.loader.WebappClassLoader @ 0x58c3a9848 org.apache.lucene.search.FieldCacheImpl

我不知道如何管理这种缓存--有什么建议吗?

最后我得到了OutOfMemoryError +12 is内存被阻塞。

EN

回答 2

Stack Overflow用户

发布于 2014-03-05 09:17:00

我实现了一种解决办法:

我创建了这样的类:

代码语言:javascript
复制
public class InternalApplicationCacheManager implements InternalApplicationCacheManagerMBean {

    public synchronized int getInternalCacheSize() {
        return FieldCache.DEFAULT.getCacheEntries().length;
    }

    public synchronized void purgeInternalCaches() {
        FieldCache.DEFAULT.purgeAllCaches();
    }
}

并通过org.apache.lucene.search.FieldCacheImpl在JMX注册。

代码语言:javascript
复制
    ...
          private synchronized void init() {
    ...
            initBeans();

          }

          private void initBeans() {
              try {
                  InternalApplicationCacheManager cacheManagerMBean = new InternalApplicationCacheManager();
                  MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
                  ObjectName name = new ObjectName("org.apache.lucene.search.jmx:type=InternalApplicationCacheManager");
                  mbs.registerMBean(cacheManagerMBean, name);
              } catch (InstanceAlreadyExistsException e) {
...
              }
          }
...

此解决方案为您提供了无效的内部缓存-这部分解决了这个问题。不幸的是,还有其他地方(主要是缓存)存储和删除一些数据,没有像我预期的那样快。

票数 1
EN

Stack Overflow用户

发布于 2014-01-16 13:53:53

如果您使用FieldCacheRangeFilter,您可能需要尝试范围筛选器,它不需要字段缓存。如果排序是一个问题,则可以尝试使用较少的排序字段或使用较少内存的数据类型字段。

每个读取器/原子读取器的字段缓存在垃圾收集时被丢弃。因此,读取器的重新初始化应该清除缓存,这也意味着使用缓存的第一次操作要慢得多。

事实是:基于FieldCache的范围筛选和排序依赖于缓存。当你真的需要这些的时候,你就不能到处走动了。您只能调整您的使用,以尽量减少内存消耗。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21163075

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档