Java 执行器服务 - 内存不足

标签 java multithreading executorservice

我正在使用 java 执行器服务将数据从一个数据库传输到另一个数据库。

ExecutorService executor = (ExecutorService) Executors.newFixedThreadPool(10);

执行器服务初始化后。以 500 条为一组从源数据库中检索记录,并将这些记录索引到目标数据库中。

while(true){  
   List<?> docs = getDataFromSourceDB();
   if(docs.size > 0){
       IndexdataToTargetDBThread thread = new IndexdataToTargetDBThread(docs)
       executor.submit(thread);
   }else{
        break;
   }
} 

executor.shutdown()
while (!eService.isTerminated()) {
}

函数 getDataFromSourceDB() 每次调用都会返回 500 条记录,如果没有可用记录,它将返回一个空数组。 IndexdataToTargetDBThread 类实现 Runnable。它将给定文档索引到目标数据库。

上述函数运行时出现Out Of Memory异常。源数据库有接近 1M 条记录,因此 while 循环被处理大约 2000 次。处理大约 700 次后,会发生内存不足,整个数据库传输过程失败。有什么有效的方法来处理这个问题吗?

最佳答案

我看到两个问题。 首先,它是从数据库获取的数据大小不受限制。您可以限制应用程序中同时存在的记录数量。创建缓冲区(它可以是一个元素有限的队列)并在准备好写入后刷新批处理:https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html )

第二:不确定数据库的隔离级别。下一篇文章介绍了 PostgreSQL 中并发插入的一些问题:https://www.postgresql.org/files/developer/concurrency.pdf

此外,您可以尝试通过 -Xmx .. 选项增加 java 内存限制: Increase heap size in Java

但这不是最好的方法:)

关于Java 执行器服务 - 内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66793701/

相关文章:

java - 我需要实现 hashCode() 和 equals() 方法吗?

java - 适用于 TTL-232R 的 Android 2.3.4 FTDI D2xx 驱动程序

java - 有没有在给它一个参数的同时运行一个线程?

python - Python3 中的线程和队列 : sentinel value in input_queue fails to break out of while loop

Android 重复任务不起作用

java - 如何使用 ExecutorService.submit(Runnable r, T result) 方法?

java - 在 Play Framework 2.x 应用程序中构建期间检测应用程序模式(DEV、TEST、PROD)

Python:防止信号传播到子线程

java - 而不是等待, "give up"一个任务,将其返回到队列并将线程释放回线程池

java - 如何在 jni 输入参数中返回 double[]