Java堆空间崩溃Solr查询

3
我不是Java专家,但使用Solr进行搜索。在搜索了这个问题后,我无法找出为什么会发生这种情况。
我的索引有3000万条记录,没有排序,我做了最轻量级的设置,但在几次查询后出现了以下异常:
严重: java.lang.OutOfMemoryError:Java堆空间 在 org.apache.lucene.index.SegmentReader.createFakeNorms(SegmentReader.java:1117) 在 org.apache.lucene.index.SegmentReader.fakeNorms(SegmentReader.java:1125) 在 org.apache.lucene.index.SegmentReader.norms(SegmentReader.java:1140) 在 org.apache.solr.search.SolrIndexReader.norms(SolrIndexReader.java:282) 在 org.apache.lucene.search.TermQuery $ TermWeight.scorer(TermQuery.java:72) 在 org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:250) 在 org.apache.lucene.search.Searcher.search(Searcher.java:171)在 org.apache.solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:988) 在 org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:884) 在 org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:341) 在 org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:182) 在 org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:195) 在 org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:131) 在 org.apache.solr.core.SolrCore.execute(SolrCore.java:1317)在 org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:338) 在 org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:241) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) 在 org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) 在 org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process(Http11Protocol.java:602) 在 org.apache.tomcat.util.net.JIoEndpoint $ Worker.run(JIoEndpoint.java:489) 在 java.lang.Thread.run(Thread.java: 679)

然后重启Tomcat,它就能继续工作了,直到再次收到若干请求而崩溃。

我希望你能帮我,但是我不需要排序(尽管我希望有),大部分时间搜索都是在特定的索引字段中进行的(而不是所有字段)。
你能帮忙吗?先谢谢了 :)

我看了那个主题并阅读了它,但大多数答案都集中在FieldCache和FieldComparator类上进行排序,而这不适用于我的情况。我使用Ubuntu的默认配置来启动守护程序,因此,我正在尝试找到增加内存限制、术语限制等的最佳方法。我手动做了这些,最初没有更好的结果。 - Marinho Brandão
您需要提供更多信息,以便我们给出提示,至少包括:JVM版本、JVM参数(特别是内存参数,如“-Xmx”、“-XX:*Size”,以及垃圾收集器参数,如“-XX:*GC”)。 - Frank Pavageau
好的,谢谢。运行进程是“/usr/lib/jvm/java-6-openjdk-amd64/bin/java -Djava.util.logging.config.file=/var/lib/tomcat6/conf/logging.properties -Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/share/tomcat6/endorsed -classpath /usr/share/tomcat6/bin/bootstrap.jar -Dcatalina.base=/var/lib/tomcat6 -Dcatalina.home=/usr/share/tomcat6 -Djava.io.tmpdir=/tmp/tomcat6-tomcat6-tmp org.apache.catalina.startup.Bootstrap start”。 - Marinho Brandão
就像我说的那样,该命令是由Ubuntu的apt-get安装的默认服务调用的。我尝试更改守护进程代码(/etc/rc3.d/*tomcat/)以强制使用不同的-Xmx和-XX,但没有效果。 - Marinho Brandão
我手动调用了“-Xmx1200m -XX:MinHeapFreeRatio=10”,它持续时间更长(稳定至今),但没有使用Ubuntu的方式。 - Marinho Brandão
2个回答

6

对于一个拥有数百万条记录的Solr部署,128MB似乎有些低了。你可以使用-Xmx增加JVM的最大大小。而-XX:MinHeapFreeRatio只是更改堆重分配的点,但你也可以使用相同值的-Xms直接分配最大大小,避免任何重分配。

然而,你可能想要尝试确定堆的更精确值,而不仅仅是盲目地扔更多内存,因为太多的内存可能会在垃圾收集期间产生较长的暂停,从而导致反生产效益。使用JVisualVM(更好的是带有VisualGC插件)或命令行上的jstat,您可以看到Solr启动后使用了多少内存,在请求后它使用了多少内存,以及通常在您的典型用法中其堆如何变化。

例如,使用jstat -gcutil <PID>,您可以看到JVM的年轻代(E,即Eden)和老年代(O)有多满(首先应查看老年代)。或者,使用jstat -gc <PID>,您将得到值而不是百分比(C列为容量,即最大值,U列为实际使用情况)。您需要足够的内存来处理Solr的工作集以及处理请求所需的内存。使用这些信息,您可以更精细地调整所需的内容。


非常感谢,这为非 Java 开发人员澄清了场景背后的逻辑 :) - Marinho Brandão

0

代码中似乎存在内存泄漏问题。您可能需要进行堆转储以查看哪些对象正在消耗内存。

(或者)

正如Brian所说,您可能正在使用较少的内存配置启动tomcat。请检查您为tomcat分配了多少内存,使用-Xms和-Xmx命令。


这是一个泄漏吗?也许它只是需要比JVM配置更多的内存? - Brian Agnew
@BrianAgnew:这是非常有价值的观点。实际上,在确定是内存泄漏之前,我们应该首先检查内存配置。 - kosa
请看一下我上面的评论 :) - Marinho Brandão

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接