Java Как удалить память в индексе Lucene, использую null, но это не приводит к результату
Я хочу создать индекс Lucene по тексту. Когда я его создаю, то выделяется память, мой тестовый метод для чтения файла и создания индекса по нему:
@Test
public void testMemory() throws IOException, InterruptedException{
System.out.println("start");
StringBuilder sb = new StringBuilder();
InMemoryLuceneIndex inMemoryLuceneIndex;
//try(FileReader reader = new FileReader("E:\\Projects\\Units\\JavaQt\\Release\\v4 - ExampleTikaRubricator\\server\\in\\files\\testQueue\\bigFile.txt"))
try(FileReader reader = new FileReader("E:\\Projects\\Units\\JavaQt\\Release\\v4 - ExampleTikaRubricator\\server\\in\\files\\testQueue\\id_14028663.TXT"))
{
int c;
while((c=reader.read())!=-1){
//System.out.print((char)c);
sb.append((char)c);
}
}
catch(IOException ex){
System.out.println(ex.getMessage());
}
System.out.println("start indexing data");
for (int i = 0; i <= 5; i++) {
System.out.println("i: "+i);
//init memory
inMemoryLuceneIndex = new InMemoryLuceneIndex(new RAMDirectory());
//Create index
inMemoryLuceneIndex.createIndex(sb.toString());
//Something work
Thread.sleep(1000);
//Clear index
inMemoryLuceneIndex.clearIndex2();
//Delete link
inMemoryLuceneIndex = null;
}
System.out.println("Start gc");
System.gc();
System.out.println("finish test");
}
В данном примере я умышленно выполняю вызов System.gc() чтобы вызвать GC.
Код, который для создания индекса:
public class InMemoryLuceneIndex {
private Directory memoryIndex; //В переменной сохраняется объект new RAMDirectory()
private HashMap<String, Integer> sortIndexWord; //Для ранжирования рубрик по их весу
private Analyzer customAnalyzer; //customAnalyzer без toLowerCase
private Map<String, Analyzer> analyzers; //<Поле, Анализатор для этого поля>
private IndexWriterConfig indexWriterConfig;
private IndexWriter writer;
public InMemoryLuceneIndex(Directory memoryIndex) throws IOException {
super();
this.memoryIndex = memoryIndex;
this.analyzers = new HashMap<>();
this.indexWriterConfig = new IndexWriterConfig(getAnalyzer());
this.writer = new IndexWriter(this.memoryIndex, indexWriterConfig);
this.sortIndexWord = new HashMap<>();
//1) init customAnalyzer без toLowerCase
this.customAnalyzer = CustomAnalyzer.builder()
.withTokenizer("standard")
.build();
//2) put data in map
this.analyzers.put("tags", new StandardAnalyzer());
this.analyzers.put("tags2", customAnalyzer);
}
public Directory getMemoryIndex(){
return this.memoryIndex;
}
public void createIndex(String content) throws IOException {
try {
Document doc = new Document();
FieldType type = new FieldType();
type.setStoreTermVectors(true);
type.setStoreTermVectorPositions(true);
type.setStoreTermVectorOffsets(true);
type.setStored(true);
type.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
Field fieldStore = new Field("tags", content, type);
doc.add(fieldStore);
FieldType type2 = new FieldType();
type2.setStoreTermVectors(true);
type2.setStoreTermVectorPositions(true);
type2.setStoreTermVectorOffsets(true);
type2.setStored(false); //Это поле не будет сохраняться
type2.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
Field fieldStore2 = new Field("tags2", content, type2);
doc.add(fieldStore2);
writer.addDocument(doc);
}
catch(Exception e){
e.printStackTrace();
}
}
public Analyzer getAnalyzer() throws IOException {
return new PerFieldAnalyzerWrapper(new StandardAnalyzer(), this.analyzers);
}
public void clearIndex2() throws IOException{
this.writer.deleteAll();
this.writer.commit();
this.writer.close();
this.memoryIndex.close();
this.indexWriterConfig = null;
this.writer = null;
this.analyzers = null;
this.customAnalyzer = null;
}
}
При этом везде, где я смотрел написано, что для удаления выделенной памяти под индекс надо использовать связку:
this.writer.deleteAll();
this.writer.commit();
Я пробовал создавать RAMDirectory, MMapDirectory, при это все равно выделяется память, потом я делаю null или делаю эти 2 команды и потом просто жду очистки, но ее не происходит, тогда я вызываю специально GC и все равно не происходит удаления, видимо есть какие-то другие способы удаления этой памяти, чтобы освободить место.
При старте приложения я устанавливаю такие параметры:
-XX:+UseSerialGC
-verbose:gc
-XX:+PrintGCDetails
Я могу посмотреть данные, но при это в диспетчере не вижу характерных данных. Тем самым получается, что происходит выделение и GC все равно не может собрать память даже если ссылка null.
Подскажите пожалуйста, как можно освободить выделенную память на индекс? Может быть есть еще какие-то другие способы? Или возможно надо использовать как-то другой GC, подскажите пожалуйста, заранее спасибо.