提交 a0b11800 authored 作者: Thomas Mueller's avatar Thomas Mueller

When opening an existing database, the cache size is set to at most half the…

When opening an existing database, the cache size is set to at most half the amount of memory available for the virtual machine.
上级 c61aec31
......@@ -18,8 +18,17 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>New system property h2.selectForUpdateMvcc, the default is false (the feature is disabled).
<ul><li>The BOM (the byte-order-mark) character 0xfeff at the beginning of the file is ignored.
This is for compatibility with Microsoft Excel.
</li><li>When opening an existing database, the cache size is set to at most
half the amount of memory available for the virtual machine
(Runtime.getRuntime().maxMemory()), even if the cache size setting stored in the database
is larger. Setting the cache size in the database URL or explicitly using SET CACHE_SIZE
overrides this value (even if larger than the physical memory).
</li><li>INFORMATION_SCHEMA.SETTINGS: the cache size is now returned in KB.
</li><li>New system property h2.selectForUpdateMvcc, the default is false (the feature is disabled).
When enabled, SELECT ... FOR UPDATE only locks the selected rows in the MVCC mode.
Aggregate or GROUP BY queries are not allowed in this case.
</li><li>Profiler: improved message if there was no stack trace.
</li><li>The H2 Console can now be used within another application, in a frame or iframe. Issue 197.
</li><li>Recover tool: the statistics section now includes page type counts again.
......
......@@ -1705,6 +1705,14 @@ The amount of memory used for caching can be changed using the setting
<code>SET CACHE_SIZE size</code>.
The size of the cache, as represented by <code>CACHE_SIZE</code> is measured in KB, with each KB being 1024 bytes.
This setting has no effect for in-memory databases.
For persistent databases, the setting is stored in the database and re-used when the database is opened
the next time. However, when opening an existing database, the cache size is set to at most
half the amount of memory available for the virtual machine (Runtime.getRuntime().maxMemory()),
even if the cache size setting stored in the database is larger; however the setting stored in the database
is kept. Setting the cache size in the database URL or explicitly using <code>SET CACHE_SIZE</code>
overrides this value (even if larger than the physical memory).
To get the current used maximum cache size, use the query
<code>SELECT * FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME = 'info.CACHE_MAX_SIZE'</code>
</p><p>
Also included is an experimental second level soft reference cache. Rows in this cache are only garbage collected
on low memory. By default the second level cache is disabled. To enable it,
......
......@@ -53,6 +53,7 @@ import org.h2.table.TableView;
import org.h2.tools.DeleteDbFiles;
import org.h2.tools.Server;
import org.h2.util.IOUtils;
import org.h2.util.MathUtils;
import org.h2.util.NetUtils;
import org.h2.util.New;
import org.h2.util.SmallLRUCache;
......@@ -1574,6 +1575,10 @@ public class Database implements DataHandler {
}
public synchronized void setCacheSize(int kb) {
if (starting) {
int max = MathUtils.convertLongToInt(Utils.getMemoryMax()) / 2;
kb = Math.min(kb, max);
}
cacheSize = kb;
if (pageStore != null) {
pageStore.getCache().setMaxSize(kb);
......
......@@ -71,21 +71,21 @@ public interface Cache {
/**
* Set the maximum memory to be used by this cache.
*
* @param size in number of double words (4 bytes)
* @param size the maximum size in KB
*/
void setMaxSize(int size);
/**
* Get the maximum size in words (4 bytes).
* Get the maximum size in KB.
*
* @return the maximum size in number of double words (4 bytes)
* @return the maximum size in KB
*/
int getMaxSize();
/**
* Get the used size in words (4 bytes).
* Get the used size in KB.
*
* @return the current size in number of double words (4 bytes)
* @return the current size in KB
*/
int getSize();
......
......@@ -22,11 +22,23 @@ public class CacheLRU implements Cache {
private final CacheWriter writer;
private final CacheObject head = new CacheHead();
private final int len;
private final int mask;
private int maxSize;
private CacheObject[] values;
private int recordCount;
/**
* The number of cache buckets.
*/
private final int len;
/**
* The maximum memory, in words (4 bytes each).
*/
private int maxSize;
/**
* The current memory used in this cache, in words (4 bytes each).
*/
private int sizeMemory;
private CacheLRU(CacheWriter writer, int maxKb) {
......@@ -304,11 +316,11 @@ public class CacheLRU implements Cache {
}
public int getMaxSize() {
return maxSize;
return maxSize * 4 / 1024;
}
public int getSize() {
return sizeMemory;
return sizeMemory * 4 / 1024;
}
}
......
......@@ -354,6 +354,7 @@ public class Utils {
/**
* Get the used memory in KB.
* This method possibly calls System.gc().
*
* @return the used memory
*/
......@@ -366,8 +367,9 @@ public class Utils {
/**
* Get the free memory in KB.
* This method possibly calls System.gc().
*
* @return the used memory
* @return the free memory
*/
public static int getMemoryFree() {
collectGarbage();
......@@ -376,6 +378,16 @@ public class Utils {
return (int) (mem >> 10);
}
/**
* Get the maximum memory in KB.
*
* @return the maximum memory
*/
public static long getMemoryMax() {
long max = Runtime.getRuntime().maxMemory();
return max / 1024;
}
private static synchronized void collectGarbage() {
Runtime runtime = Runtime.getRuntime();
long total = runtime.totalMemory();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论