我不是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,它恢复工作,直到再次要求掉落的请求。
我大多数时候都没有按特定的索引字段(并非全部针对它们)进行排序(甚至是我希望的)和搜索。
你可以帮帮我吗?提前致谢 :)
最佳答案
对于具有数百万条记录的Solr部署来说,128 MB似乎很低。您确实可以使用-Xmx
增加JVM的最大大小。 -XX:MinHeapFreeRatio
只是更改了调整堆大小的点,但是您也可以使用与-Xms
相同的值的-Xmx
直接分配最大大小并避免任何大小调整。
但是,您可能想要尝试为堆确定一个更精确的值,而不是仅仅盲目地抛出更多的内存,因为过多的内存可能会适得其反,因此,由于垃圾回收期间的暂停时间较长。在命令行上使用JVisualVM(甚至使用VisualGC插件,甚至更好),或在命令行上使用jstat
,您可以看到Solr启动后使用了多少内存,请求后使用了多少内存以及通常在您的典型用法期间其堆如何变化。
例如,使用jstat -gcutil <PID>
,您可以看到JVM的年轻(Eden)(如在Eden中)和老(O)代(第一代应该是老一代)有多满。或使用jstat -gc <PID>
,您将获得值而不是百分比(C列为容量,即最大值,U列为实际用量)。您需要足够的内存来存储Solr的工作集以及处理请求所需的内容。使用这些信息,您可以更精细地调整所需的内容。