数据库连接和 OutOfMemoryError:Java 堆空间

2024-02-26

去年夏天,我制作了一个 Java 应用程序,它可以解析一些 PDF 文件并获取它们包含的信息并将其存储在 SQLite 数据库中。

一切都很好,我每周左右都会向数据库添加新文件,没有任何问题。

现在,我正在尝试提高应用程序的速度,我想看看如果我在新数据库中解析过去两年的所有文件,效果会如何。那是我开始收到此错误的时候:OutOfMemoryError:Java 堆空间。我之前没有得到它,因为我每周只解析大约 25 个新文件,但似乎逐个解析 1000 多个文件要求更高。

我部分解决了这个问题:我确保在每次调用数据库后关闭连接,并且错误消失,但代价高昂。现在解析文件的速度慢得难以忍受。至于我的结果集和语句/准备语句,我已经在每次调用后关闭它们。

我想我不明白什么时候应该关闭连接以及什么时候应该继续重复使用同一个连接。我认为,由于自动提交已打开,因此它会在每个事务(选择、更新、插入等)之后提交,并且连接会释放它正在使用的额外内存。我可能是错的,因为当我解析太多文件时,我最终会收到我提到的错误。

一个简单的解决方案是在每次 x 调用后关闭它,但我又不明白为什么,以后可能会遇到相同的错误。谁能解释一下我什么时候应该关闭我的连接(如果有的话,除了我完成时之外)?如果我只应该在完成后执行此操作,那么有人可以解释我应该如何避免此错误吗?

顺便说一句,我没有将其标记为 SQLite,因为当我尝试在在线 MySQL 数据库上运行我的程序时,我遇到了同样的错误。

Edit正如德科和马夫拉夫所指出的,也许问题不在于我的连接。也许是文件的问题,所以我将把我用来调用函数解析文件的代码一一贴出来:

public static void visitAllDirsAndFiles(File dir){
    if (dir.isDirectory()){
        String[] children = dir.list();

        for (int i = 0; i < children.length; i++){
            visitAllDirsAndFiles(new File(dir, children[i]));
        }
    }
    else{
        try{
            // System.out.println("File: " + dir);
            BowlingFilesReader.readFile(dir, playersDatabase);
        }
        catch (Exception exc){
            System.out.println("Other exception in file: " + dir);
        }
    }
}

因此,如果我使用目录调用该方法,它会使用我刚刚创建的 File 对象再次递归地调用该函数。然后我的方法检测到它是一个文件并调用BowlingFilesReader.readFile(dir,playersDatabase);

我认为该方法完成后应该释放内存吗?


您对开放结果集和连接的第一直觉是好的,尽管可能不完全是原因。让我们首先从数据库连接开始。

Database

尝试使用数据库连接池库,例如 Apache Commons DBCP(BasicDataSource 是一个很好的起点):http://commons.apache.org/dbcp/ http://commons.apache.org/dbcp/您仍然需要关闭数据库对象,但这将使数据库前端的工作顺利运行。


JVM内存

增加分配给 JVM 的内存大小。您可以通过添加 -Xmx 和后面的内存量来做到这一点,例如:

  • -Xmx64m
  • -Xmx512m

不过,要小心你的数字,向 JVM 投入更多内存并不能解决内存泄漏问题。您可以使用 JConsole 或 JVisualVM(包含在 JDK 的 bin/ 文件夹中)之类的工具来观察您使用了多少内存。

螺纹加工

假设您执行的解析这些记录的操作是可线程化的,您可以通过将操作线程化来提高操作速度。但可能需要更多信息才能回答这个问题。

希望这可以帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据库连接和 OutOfMemoryError:Java 堆空间 的相关文章

随机推荐