Database H2服务器使用1G内存加载一个250m基于文件的数据库?

Database H2服务器使用1G内存加载一个250m基于文件的数据库?,database,memory,load,h2,Database,Memory,Load,H2,我从应用程序用户那里收到几个报告,在连接到H2服务器时出现内存不足异常。在尝试复制时,我使用jconsole连接到H2服务器并检查发生了什么 我发现当我第一次连接到H2服务器并加载数据库时,H2服务器开始消耗大量内存。在加载任何数据库之前,H2服务器只消耗3M内存。使用SquirrelSQL客户端连接H2并加载250M文件数据库后,H2服务器消耗约1G内存。发生这种情况的原因是什么 H2服务器启动命令: java-Xmx2g-Xms16m-XX:PermSize=16m-XX:MaxPermSi

我从应用程序用户那里收到几个报告,在连接到H2服务器时出现内存不足异常。在尝试复制时,我使用jconsole连接到H2服务器并检查发生了什么

我发现当我第一次连接到H2服务器并加载数据库时,H2服务器开始消耗大量内存。在加载任何数据库之前,H2服务器只消耗3M内存。使用SquirrelSQL客户端连接H2并加载250M文件数据库后,H2服务器消耗约1G内存。发生这种情况的原因是什么

H2服务器启动命令: java-Xmx2g-Xms16m-XX:PermSize=16m-XX:MaxPermSize=256m-cp“h2-1.3.173.jar;%H2DRIVERS%;%CLASSPATH%”org.h2.tools.Server-tcp-tcpPort 9097-tcpallowsethers-baseDir C:\temp\h2db

我的连接字符串:jdbc:h2:tcp://localhost:9097/db1;DB_关闭_延迟=-1


其他信息:
我们在数据库中有相当多的表(1200+)和800多个视图,它们在这些表上进行联合或联接。这就是问题的原因吗?在加载这样的数据库时,是否有任何解决方案可以减少内存消耗?

在分析堆转储后,发现这些内存中的大部分都被视图元数据占用。在我们的例子中,有2500多个视图,它们的元数据占用了550M的堆大小。有关这方面的详细讨论,请参见:


Thomas承认应改进当前的h2视图元数据以减少内存使用。

分析堆转储后,发现这些内存中的大部分都被视图元数据占用。在我们的例子中,有2500多个视图,它们的元数据占用了550M的堆大小。有关这方面的详细讨论,请参见:


Thomas承认应该改进当前的h2视图元数据以减少内存使用。

好吧,您允许它消耗高达2G的堆(
-Xmx2g
),这样JVM就不会受到永久gc的激励。如果将-Xmx设置降低到
-Xmx128m
,会发生什么情况?另外,您确定要创建的数据库是磁盘数据库而不是内存数据库吗?即使使用-Xmx512M,服务器也无法加载250M数据库,并且会报告内存不足。当使用2G堆时,在加载数据库并强制它执行GC之后,仍然使用了大约800M的堆内存。数据库肯定存储在磁盘上,因为我可以看到大小为250M的db1.h2.db文件。我认为我的连接字符串将其指定为基于文件的数据库,而不是内存中的数据库。我说的对吗?不,您的连接将其指定为服务器连接,但服务器可以提供对持久数据库和内存数据库的访问。在仅磁盘模式下运行时,h2不需要2GB来运行db。我认为对于h2连接字符串,只有在指定“mem:”时,它才会是内存数据库。在我的例子中,我没有指定这个选项,所以db1应该是一个文件数据库。为了验证这一点,我使用了一个新的连接字符串:jdbc:h2:tcp://localhost:9097/file:db1;DB_CLOSE_DELAY=-1,它为db1声明“file:”选项以确保它是file DB。这个问题仍然存在,没错。您可能希望在加载数据库后生成一个heapdump,并使用JVisualVM或eclipsemat查看它,以查看所有内存的去向。自从我上次用h2做“大”和持久化的事情已经有一段时间了,但是您描述的不是它的正常行为……好吧,您允许它消耗高达2G的堆(
-Xmx2g
),所以JVM不会受到永久gc的激励。如果将-Xmx设置降低到
-Xmx128m
,会发生什么情况?另外,您确定要创建的数据库是磁盘数据库而不是内存数据库吗?即使使用-Xmx512M,服务器也无法加载250M数据库,并且会报告内存不足。当使用2G堆时,在加载数据库并强制它执行GC之后,仍然使用了大约800M的堆内存。数据库肯定存储在磁盘上,因为我可以看到大小为250M的db1.h2.db文件。我认为我的连接字符串将其指定为基于文件的数据库,而不是内存中的数据库。我说的对吗?不,您的连接将其指定为服务器连接,但服务器可以提供对持久数据库和内存数据库的访问。在仅磁盘模式下运行时,h2不需要2GB来运行db。我认为对于h2连接字符串,只有在指定“mem:”时,它才会是内存数据库。在我的例子中,我没有指定这个选项,所以db1应该是一个文件数据库。为了验证这一点,我使用了一个新的连接字符串:jdbc:h2:tcp://localhost:9097/file:db1;DB_CLOSE_DELAY=-1,它为db1声明“file:”选项以确保它是file DB。这个问题仍然存在,没错。您可能希望在加载数据库后生成一个heapdump,并使用JVisualVM或eclipsemat查看它,以查看所有内存的去向。我上次用h2做“大”和持久的事情已经有一段时间了,但你描述的不是它的正常行为。。。