如何有效地(即 w/o 内存泄漏)检索 Solr 索引中已经存在的文档?

How to efficiently (ie w/o memory leaks) retrieve already exising documents in a Solr index?

我认为我的方法正在泄漏内存,因为在探查器中 "Surviving generations" 的数量不断增加:

在生产中,我在一段时间后收到 "OOM heap space" 错误,现在我认为我的方法是罪魁祸首。

作为背景,我的方法目标是检索索引中已经存在的文档。然后使用该列表来判断文档是否可以保留在索引中或可以删除​​(例如,相应的文档已从磁盘中删除):

public final List<MyDocument> getListOfMyDocumentsAlreadyIndexed() throws SolrServerException, HttpSolrClient.RemoteSolrException, IOException {

 final SolrQuery query = new SolrQuery("*:*");

query.addField("id");
query.setRows(Integer.MAX_VALUE); // we want ALL documents in the index not only the first ones

SolrDocumentList results = this.getSolrClient().
    query(
            query).getResults();

listOfMyDocumentsAlreadyIndexed = results.parallelStream() // tried to replace with stream with the same behaviour
    .map((doc) -> {

        MyDocument tmpDoc = new MyDocument();

        tmpDoc.setId((String) doc.getFirstValue(
                "id"));

                // Usually there are things done here to set some boolean fields
                // that I have removed for the test and this question

        return tmpDoc;
    })
    .collect(Collectors.toList());        

return listOfMyDocumentsAlreadyIndexed;
}

此方法的测试在 for 循环中执行以下调用 300 次(这模拟了索引循环,因为我的程序一个接一个地索引索引):

List<MyDocument> listOfExistingDocsInIndex = index.getListOfMyDocumentsAlreadyIndexed();

我试过用完后作废(测试没用,就是看看有没有效果),没有明显变化: listOfExistingDocsInIndex = null;

这是我从 Netbeans 探查器获得的调用树(我刚刚开始使用探查器):

我可以更改/改进什么来避免此内存泄漏(这实际上是内存泄漏,不是吗?)?

感谢任何帮助:-),

到目前为止,我发现要避免在从索引中检索所有文档时发生内存泄漏,必须避免使用 :

query.setRows(Integer.MAX_VALUE);

取而代之的是,必须按块大小所在的块来逐块检索文档 between 100 and 200 documents as depicted in Solr's wiki :

SolrQuery q = (new SolrQuery(some_query)).setRows(r).setSort(SortClause.asc("id"));
String cursorMark = CursorMarkParams.CURSOR_MARK_START;
boolean done = false;
while (! done) {
  q.set(CursorMarkParams.CURSOR_MARK_PARAM, cursorMark);
  QueryResponse rsp = solrServer.query(q);
  String nextCursorMark = rsp.getNextCursorMark();
  doCustomProcessingOfResults(rsp);
  if (cursorMark.equals(nextCursorMark)) {
    done = true;
  }
  cursorMark = nextCursorMark;
}

现在幸存的世代随着时间的推移保持稳定:

缺点是垃圾收集器更活跃,检索速度更慢(我没有对它进行基准测试,所以我没有指标可以显示)。