mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

boli
31.52.2007 ddfb6e5c119b5a6cd89e088cc185e2c4d77ef0f8
Fixed a issue where closing the JE backend may cause memory leaks. With this fix, only one database handle is opened per database container.


1 files modified
78 ■■■■ changed files
opends/src/server/org/opends/server/backends/jeb/DatabaseContainer.java 78 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/jeb/DatabaseContainer.java
@@ -28,8 +28,6 @@
import com.sleepycat.je.*;
import java.util.concurrent.CopyOnWriteArrayList;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
@@ -66,16 +64,10 @@
  private Environment env;
  /**
   * A list of JE database handles opened through this database
   * A JE database handle opened through this database
   * container.
   */
  private CopyOnWriteArrayList<Database> databases;
  /**
   * A cached per-thread JE database handle.
   */
  private ThreadLocal<Database> threadLocalDatabase =
      new ThreadLocal<Database>();
  private Database database;
  /**
   * Create a new DatabaseContainer object.
@@ -91,7 +83,6 @@
  {
    this.env = env;
    this.entryContainer = entryContainer;
    this.databases = new CopyOnWriteArrayList<Database>();
    this.name = name;
  }
@@ -99,20 +90,12 @@
   * Opens a JE database in this database container. If the provided
   * database configuration is transactional, a transaction will be
   * created and used to perform the open.
   * <p>
   * Note that a database can be opened multiple times and will result in
   * multiple unique handles to the database.  This is used for example to
   * give each server thread its own database handle to eliminate contention
   * that could occur on a single handle.
   *
   * @return A new JE database handle.
   * @throws DatabaseException If an error occurs while attempting to open the
   * database.
   * @throws DatabaseException if a JE database error occurs while
   * openning the index.
   */
  private Database openDatabase() throws DatabaseException
  public void open() throws DatabaseException
  {
    Database database;
    if (dbConfig.getTransactional())
    {
      // Open the database under a transaction.
@@ -144,31 +127,6 @@
                            database.getDatabaseName(), database.count());
      }
    }
    return database;
  }
  private Database getDatabase() throws DatabaseException
  {
    Database database = threadLocalDatabase.get();
    if (database == null)
    {
      database = openDatabase();
      databases.add(database);
      threadLocalDatabase.set(database);
    }
    return database;
  }
  /**
   * Open the database container.
   *
   * @throws DatabaseException if a JE database error occurs while
   * openning the index.
   */
  public void open() throws DatabaseException
  {
    getDatabase();
  }
  /**
@@ -188,25 +146,17 @@
   */
  synchronized void close() throws DatabaseException
  {
    // Close each database handle that has been opened.
    for (Database database : databases)
    if(dbConfig.getDeferredWrite())
    {
      if (database.getConfig().getDeferredWrite())
      {
        database.sync();
      }
      database.close();
      database.sync();
    }
    database.close();
    database = null;
    if(debugEnabled())
    {
      TRACER.debugInfo("Closed database %s (%d handles)", name,
                       databases.size());
      TRACER.debugInfo("Closed database %s", name);
    }
    databases.clear();
    threadLocalDatabase = new ThreadLocal<Database>();
  }
  /**
@@ -222,7 +172,6 @@
                                DatabaseEntry data)
      throws DatabaseException
  {
    Database database = getDatabase();
    OperationStatus status = database.put(txn, key, data);
    if (debugEnabled())
    {
@@ -248,7 +197,6 @@
                                 LockMode lockMode)
      throws DatabaseException
  {
    Database database = getDatabase();
    OperationStatus status = database.get(txn, key, data, lockMode);
    if (debugEnabled())
    {
@@ -271,7 +219,6 @@
                                   DatabaseEntry key, DatabaseEntry data)
      throws DatabaseException
  {
    Database database = getDatabase();
    OperationStatus status = database.putNoOverwrite(txn, key, data);
    if (debugEnabled())
    {
@@ -293,7 +240,6 @@
                                   DatabaseEntry key)
      throws DatabaseException
  {
    Database database = getDatabase();
    OperationStatus status = database.delete(txn, key);
    if (debugEnabled())
    {
@@ -315,7 +261,6 @@
  public Cursor openCursor(Transaction txn, CursorConfig cursorConfig)
       throws DatabaseException
  {
    Database database = getDatabase();
    return database.openCursor(txn, cursorConfig);
  }
@@ -327,7 +272,6 @@
   */
  public long getRecordCount() throws DatabaseException
  {
    Database database = getDatabase();
    long count = database.count();
    if (debugEnabled())
    {
@@ -367,7 +311,7 @@
  public PreloadStats preload(PreloadConfig config)
      throws DatabaseException
  {
    return getDatabase().preload(config);
    return database.preload(config);
  }
  /**