【问题标题】:How to avoid "Out Of Memory" error when connecting to Access database?连接Access数据库时如何避免“Out Of Memory”错误?
【发布时间】:2016-03-01 21:53:05
【问题描述】:

我有一个本地 MS Access 数据库,我正在尝试通过 Java 连接到它。我使用 UCanAccess 作为 JDBC 驱动程序,虽然数据库链接到网络驱动器上受密码保护的数据库,但我连接的数据库已经过身份验证,并且本身没有密码保护。我的类路径中有所有依赖项。连接时,我不断收到此错误:

java.lang.OutOfMemoryError: Java 堆

我启动了 Java VisualVM,确实,主线程正在占用所有分配的 2GB 内存。只有当我尝试从大型 MySQL 数据库中选择大量记录时,才会发生这种情况。我在 Google 上找不到与连接时发生的这种情况相关的任何结果,因为我什至没有尝试查询数据库。

代码很简单:

Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
System.out.println("Initiating connection...");
conn = DriverManager.getConnection("jdbc:ucanaccess://C:/Databases/StoreSalesCurrent.accdb");
System.out.println("Connection established");
conn.close();

知道为什么只是尝试建立连接会导致如此大的内存消耗吗?

【问题讨论】:

  • 我的女朋友也尝试过同样的事情,虽然她从来没有遇到过这个特殊的错误,但她永远无法让 JDBC 驱动程序与 MS Access 一起工作。她尝试的驱动程序只是为了证明这是可能的概念,而不是被认真使用。此外,在 Java 8 中,她使用的驱动程序不再作为桥接所使用的特定方法工作。但是,我不确定您的代码是否属于这种情况。我的女朋友最终放弃了 MS Access,开始使用 postgresql 数据库。
  • @Taelsin - UCanAccess 是一个纯 Java 解决方案,它不使用 JDBC-ODBC 桥,因此它在 Java 8 下运行良好。
  • @TheDankOG - 尝试将 ;memory=false 附加到您的连接 URL 中,看看是否有帮助。

标签: java ms-access jdbc ms-access-2007 ucanaccess


【解决方案1】:

默认情况下,UCanAccess 在 JVM 生命周期的第一个连接时将整个数据库加载到内存中。这被选为默认行为,因为典型的用例是针对较小的个人数据库,而不是千兆字节大小的数据库。

它可以使用正确的连接参数,例如设置memory=false 和可能的其他相关选项,但启动时间(JVM 生命中第一次连接的时间)可能会变长。有关详细信息,请参阅UCanAccess website

【讨论】:

  • 数据库不是 2gb,大约是 1.1gb,这就是为什么我为 JVM 分配 2gb,以允许它加载整个数据库并为查询执行提供一些开销空间。当我有机会时,我会尝试使用 memory=false 标志。编辑:连接需要很长时间,但至少 JVisualVM 中的堆没有爆炸。
  • 您可能希望在 memory=false 之前使用 Skipindexes=true(它不会影响参照完整性约束)来最小化内存占用。事实上,意外的内存占用可能是由于索引造成的,但如果您可以使用 memory=true,您将在查询执行中体验良好的性能。
猜你喜欢
  • 2019-06-23
  • 2018-08-06
  • 2012-03-09
  • 1970-01-01
  • 2022-09-28
  • 2016-07-09
  • 2019-01-09
  • 2018-08-01
  • 1970-01-01
相关资源
最近更新 更多