2012-09-17 106 views
3

我不是一个Java的家伙,但使用Solr进行搜索,但在搜索这个问题后,我找不到它为什么会发生。Java堆空间崩溃Solr查询

我有3000万条记录,指数没有排序,我可以做最轻的设置,但我有几个疑问后,以下情况除外:

SEVERE: java.lang.OutOfMemoryError: Java heap space at org.apache.lucene.index.SegmentReader.createFakeNorms(SegmentReader.java:1117) at org.apache.lucene.index.SegmentReader.fakeNorms(SegmentReader.java:1125) at org.apache.lucene.index.SegmentReader.norms(SegmentReader.java:1140) at org.apache.solr.search.SolrIndexReader.norms(SolrIndexReader.java:282) at org.apache.lucene.search.TermQuery$TermWeight.scorer(TermQuery.java:72) at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:250) at org.apache.lucene.search.Searcher.search(Searcher.java:171) at org.apache.solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:988) at org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:884) at org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:341) at org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:182) at org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:195) at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:131) at org.apache.solr.core.SolrCore.execute(SolrCore.java:1317) at org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:338) at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:241) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:679)

然后我重新启动Tomcat和它得到重新开始工作,直到有几次再次摔倒。

我没有排序(即使我希望它)和搜索操作系统大多数时间由特定的索引字段(而不是所有的)。

你能帮我吗?在此先感谢:)

+0

[如何确保Solr/Lucene不会死于java.lang.OutOfMemoryError?](http://stackoverflow.com/questions/2391758/how-to-make-sure-solr-lucene -wont-die-with-java-lang-outofmemoryerror) –

+0

我看到了该主题并阅读了它,但答案主要集中在FieldCache和FieldComparator类中进行排序,这不是我的情况。我使用Ubuntu的默认配置来启动守护进程,因此,我试图找出增加内存限制,术语限制等的最佳方式。我手动完成了它,并且最初没有更好的结果。 –

+0

您需要提供更多信息,以便我们给出提示,至少:JVM的版本,JVM参数(特别是内存参数,例如'-Xmx','-XX:* Size'和垃圾收集器参数等作为'-XX:* GC')。 –

回答

6

对于具有几百万条记录的Solr部署,128 MB似乎很低。您确实可以使用-Xmx来增加JVM的最大大小。 -XX:MinHeapFreeRatio只是改变堆大小的点,但也可以使用与-Xmx相同的值-Xms直接分配最大大小并避免任何大小调整。

但是,您可能希望尝试为堆确定更精确的值,而不是盲目地抛出更多内存,因为太多的内存可能会造成反向延迟,因为垃圾回收期间的停顿时间较长。在命令行上使用JVisualVM(甚至更好,使用VisualGC插件)或jstat,您可以看到Solr启动后使用了多少内存,请求后使用了多少内存,以及在典型使用情况下它的堆大小如何变化。

例如,使用jstat -gcutil <PID>,您可以看到JVM的年轻人(E,如Eden)和老年人(O)的年代(起初是您应该关注的老一代)。或者使用jstat -gc <PID>,您将得到值而不是百分比(C列是容量,即最大值,U列是实际使用量)。您需要足够的内存用于Solr的工作集以及处理请求所需的内容。使用这些信息,您可以更精确地调整需要的内容。

+0

非常感谢,这澄清了非java dev的场景背后的逻辑:) –

0

看来你有代码中的内存泄漏。您可能需要使用堆转储来查看哪些对象正在消耗内存。

(或)

正如布赖恩说,你可能会起tomcat用更少的内存配置。使用-Xms和-Xmx命令检查为tomcat分配了多少内存。

+0

它是一个泄漏吗?也许它只是需要比JVM配置更多的内存? –

+0

@BrianAgnew:这是非常有效的点,其实我们应该首先检查内存配置才决定它是内存泄漏。 – kosa

+0

请看看我的评论以上:) –