Shutdown executor for auto-commiting Lucene index when stopping Gerrit
If the executor is not shut down a reference to the Lucene index is
kept in memory. This memory leak became a problem when running the
acceptance tests, because for every test we start/stop a Gerrit
instance. This problem got worse since we are having the account
index, since the account index references the account cache which then
also stays in memory. Finally for some changes (e.g. see comments on
[1]) this resulted in tests failing with:
java.lang.OutOfMemoryError: GC overhead limit exceeded
[1] https://gerrit-review.googlesource.com/79089
Change-Id: I9a6c2f3c73137d380585869a3a90b0d013c9cdf1
Signed-off-by: Edwin Kempin <ekempin@google.com>
diff --git a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/AbstractLuceneIndex.java b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/AbstractLuceneIndex.java
index b40d46b..1bbc75d 100644
--- a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/AbstractLuceneIndex.java
+++ b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/AbstractLuceneIndex.java
@@ -88,6 +88,7 @@
private final ReferenceManager<IndexSearcher> searcherManager;
private final ControlledRealTimeReopenThread<IndexSearcher> reopenThread;
private final Set<NrtFuture> notDoneNrtFutures;
+ private ScheduledThreadPoolExecutor autoCommitExecutor;
AbstractLuceneIndex(
Schema<V> schema,
@@ -115,11 +116,11 @@
new AutoCommitWriter(dir, writerConfig.getLuceneConfig());
delegateWriter = autoCommitWriter;
- new ScheduledThreadPoolExecutor(1, new ThreadFactoryBuilder()
+ autoCommitExecutor = new ScheduledThreadPoolExecutor(1, new ThreadFactoryBuilder()
.setNameFormat("Commit-%d " + index)
.setDaemon(true)
- .build())
- .scheduleAtFixedRate(new Runnable() {
+ .build());
+ autoCommitExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
@@ -188,6 +189,10 @@
@Override
public void close() {
+ if (autoCommitExecutor != null) {
+ autoCommitExecutor.shutdown();
+ }
+
reopenThread.close();
// Closing the reopen thread sets its generation to Long.MAX_VALUE, but we