Я тестирую запрос с помощью jSolr (7.4), потому что считаю, что он вызывает утечку памяти в моей программе. Но я не уверен, что это действительно утечка памяти, поэтому обращаюсь за советом!
Этот метод вызывается несколько раз во время работы моей программы индексирования (должна быть в состоянии работать недели / месяцы без каких-либо проблем. ). Вот почему я тестирую его на al oop, который я профилирую с помощью Netbeans Profiler.
Если я просто извлекаю идентификатор из всех документов (их 33k) в данном индексе:
public class MyIndex {
// This is used as a cache variable to avoid querying the index everytime the list of documents is needed
private List<MyDocument> listOfMyDocumentsAlreadyIndexed = null;
public final List<MyDocument> getListOfMyDocumentsAlreadyIndexed() throws SolrServerException, HttpSolrClient.RemoteSolrException, IOException {
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();
/**
* The following was commented for the test,
* so that it can be told where the leak comes from.
*
*/
// listOfMyDocumentsAlreadyIndexed = results.parallelStream()
// .map((doc) -> { // different stuff ...
// return myDocument;
// })
// .collect(Collectors.toList());
return listOfMyDocumentsAlreadyIndexed;
/** The number of surviving generations
* keeps increasing whereas if null is
* returned then the number of surviving
* generations is not increasing anymore
*/
}
Я получаю это от профилировщика (после почти 200 запусков, которые могут имитировать год выполнения моей программы):
Объект, который является наиболее выживающим является String
:
Является ли ожидаемое поведение растущего числа выживших поколений ожидаемым поведением при запросе всех документов в индексе?
Если это так, то причина root ошибки «OOM Java heap space», которую я получаю через некоторое время на производственном сервере, как кажется, из трассировки стека:
Exception in thread "Timer-0" java.lang.OutOfMemoryError: Java heap space
at org.noggit.CharArr.resize(CharArr.java:110)
at org.noggit.CharArr.reserve(CharArr.java:116)
at org.apache.solr.common.util.ByteUtils.UTF8toUTF16(ByteUtils.java:68)
at org.apache.solr.common.util.JavaBinCodec.readStr(JavaBinCodec.java:868)
at org.apache.solr.common.util.JavaBinCodec.readStr(JavaBinCodec.java:857)
at org.apache.solr.common.util.JavaBinCodec.readObject(JavaBinCodec.java:266)
at org.apache.solr.common.util.JavaBinCodec.readVal(JavaBinCodec.java:256)
at org.apache.solr.common.util.JavaBinCodec.readSolrDocument(JavaBinCodec.java:541)
at org.apache.solr.common.util.JavaBinCodec.readObject(JavaBinCodec.java:305)
at org.apache.solr.common.util.JavaBinCodec.readVal(JavaBinCodec.java:256)
at org.apache.solr.common.util.JavaBinCodec.readArray(JavaBinCodec.java:747)
at org.apache.solr.common.util.JavaBinCodec.readObject(JavaBinCodec.java:272)
at org.apache.solr.common.util.JavaBinCodec.readVal(JavaBinCodec.java:256)
at org.apache.solr.common.util.JavaBinCodec.readSolrDocumentList(JavaBinCodec.java:555)
at org.apache.solr.common.util.JavaBinCodec.readObject(JavaBinCodec.java:307)
at org.apache.solr.common.util.JavaBinCodec.readVal(JavaBinCodec.java:256)
at org.apache.solr.common.util.JavaBinCodec.readOrderedMap(JavaBinCodec.java:200)
at org.apache.solr.common.util.JavaBinCodec.readObject(JavaBinCodec.java:274)
at org.apache.solr.common.util.JavaBinCodec.readVal(JavaBinCodec.java:256)
at org.apache.solr.common.util.JavaBinCodec.unmarshal(JavaBinCodec.java:178)
at org.apache.solr.client.solrj.impl.BinaryResponseParser.processResponse(BinaryResponseParser.java:50)
at org.apache.solr.client.solrj.impl.HttpSolrClient.executeMethod(HttpSolrClient.java:614)
at org.apache.solr.client.solrj.impl.HttpSolrClient.request(HttpSolrClient.java:255)
at org.apache.solr.client.solrj.impl.HttpSolrClient.request(HttpSolrClient.java:244)
at org.apache.solr.client.solrj.SolrRequest.process(SolrRequest.java:194)
at org.apache.solr.client.solrj.SolrClient.query(SolrClient.java:942)
at org.apache.solr.client.solrj.SolrClient.query(SolrClient.java:957)
Будет ли увеличение объема кучи («-Xmx») с 8 ГБ до большего решает проблему определенно, или это просто откладывает ее? Что можно сделать, чтобы обойти это?
Изменить через несколько часов
Если null
возвращается из тестируемого метода (getListOfMyDocumentsAlreadyIndexed
), то количество выжившие поколения остаются стабильными на протяжении всего теста:
Таким образом, хотя я НЕ использовал результат запроса для этого теста (потому что я хотел сфокусироваться только в том месте, где произошла утечка) похоже, что возвращение переменной экземпляра (даже если она была нулевой) не является хорошей идеей. Я попытаюсь удалить его.
Редактировать даже позже
Я заметил, что выжившие поколения все еще увеличивались на вкладке телеметрии, когда я профилировал «определенные классы» ( "сфокусированный (инструментированный)"), тогда как он был стабильным при профилировании "Все классы" ("Общие (выборочные)"). Поэтому я не уверен, что это решило проблему:
Любые подсказки приветствуются : -)