提交 50b5f52a authored 作者: Thomas Mueller's avatar Thomas Mueller

Less heap memory is needed when multiple databases are open at the same time.

上级 53e6320d
......@@ -17,6 +17,7 @@ import org.h2.message.Trace;
import org.h2.message.TraceObject;
import org.h2.result.LocalResult;
import org.h2.result.ResultInterface;
import org.h2.util.MemoryUtils;
import org.h2.util.ObjectArray;
/**
......@@ -193,7 +194,7 @@ public abstract class Command implements CommandInterface {
public int executeUpdate() throws SQLException {
long start = startTime = System.currentTimeMillis();
Database database = session.getDatabase();
database.allocateReserveMemory();
MemoryUtils.allocateReserveMemory();
Object sync = database.isMultiThreaded() ? (Object) session : (Object) database;
session.waitIfExclusiveModeEnabled();
synchronized (sync) {
......@@ -205,7 +206,7 @@ public abstract class Command implements CommandInterface {
try {
return update();
} catch (OutOfMemoryError e) {
database.freeReserveMemory();
MemoryUtils.freeReserveMemory();
throw Message.convert(e);
} catch (SQLException e) {
if (e.getErrorCode() == ErrorCode.CONCURRENT_UPDATE_1) {
......
......@@ -154,13 +154,12 @@ public class Database implements DataHandler {
private boolean multiVersion;
private DatabaseCloser closeOnExit;
private Mode mode = Mode.getInstance(Mode.REGULAR);
// TODO change in version 1.1
// TODO change in version 1.2
private boolean multiThreaded;
private int maxOperationMemory = SysProperties.DEFAULT_MAX_OPERATION_MEMORY;
private boolean lobFilesInDirectories = SysProperties.LOB_FILES_IN_DIRECTORIES;
private SmallLRUCache lobFileListCache = new SmallLRUCache(128);
private boolean autoServerMode;
private Object reserveMemory;
private Server server;
private HashMap linkConnections;
private TempFileDeleter tempFileDeleter = TempFileDeleter.getInstance();
......@@ -2022,7 +2021,8 @@ public class Database implements DataHandler {
}
public void setMultiThreaded(boolean multiThreaded) throws SQLException {
if (multiThreaded && multiVersion) {
if (multiThreaded && multiVersion && this.multiThreaded != multiThreaded) {
// currently the combination of MVCC and MULTI_THREADED is not supported
throw Message.getSQLException(ErrorCode.CANNOT_CHANGE_SETTING_WHEN_OPEN_1, "MVCC & MULTI_THREADED");
}
this.multiThreaded = multiThreaded;
......@@ -2061,23 +2061,6 @@ public class Database implements DataHandler {
return meta.isLockedExclusively();
}
/**
* Allocate a little main memory that is freed up when if no memory is
* available, so that rolling back a large transaction is easier.
*/
public void allocateReserveMemory() {
if (reserveMemory == null) {
reserveMemory = new byte[SysProperties.RESERVE_MEMORY];
}
}
/**
* Free up the reserve memory.
*/
public void freeReserveMemory() {
reserveMemory = null;
}
/**
* Open a new connection or get an existing connection to another database.
*
......
......@@ -6,6 +6,8 @@
*/
package org.h2.util;
import org.h2.constant.SysProperties;
/**
* This is a utility class with functions to measure the free and used memory.
*/
......@@ -14,6 +16,7 @@ public class MemoryUtils {
private static long lastGC;
private static final int GC_DELAY = 50;
private static final int MAX_GC = 8;
private static volatile byte[] reserveMemory;
private MemoryUtils() {
// utility class
......@@ -60,4 +63,21 @@ public class MemoryUtils {
}
}
/**
* Allocate a little main memory that is freed up when if no memory is
* available, so that rolling back a large transaction is easier.
*/
public static void allocateReserveMemory() {
if (reserveMemory == null) {
reserveMemory = new byte[SysProperties.RESERVE_MEMORY];
}
}
/**
* Free up the reserve memory.
*/
public static void freeReserveMemory() {
reserveMemory = null;
}
}
......@@ -37,6 +37,9 @@ public class TestOutOfMemory extends TestBase {
if (config.memory || config.mvcc) {
return;
}
for (int i = 0; i < 5; i++) {
System.gc();
}
deleteDb("outOfMemory");
Connection conn = getConnection("outOfMemory");
Statement stat = conn.createStatement();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论