我要先说明一下,我相对于Java/Scala来说还是个新手,所以不能排除有些明显的问题我可能没有注意到。
我有一个Scala应用程序,它通过Hibernate连接到MySQL数据库。该应用程序旨在处理大量数据,约为2,750,000条记录,因此我尽可能地进行了优化。
它运行在我的工作站上,这是一台四核Intel Xeon处理器,配备6GB RAM(1033Mhz),并且在前70k条记录中运行得很好和迅速,完成时间约为15分钟。但到了90k时,它已经花费了约25分钟,变得非常缓慢。
我已经检查了Hibernate代码的计时器,并且发现数据库检索所花费的时间与通常相同。我甚至尝试强制手动垃圾回收,但也不起作用。
相关代码如下:
我有一个Scala应用程序,它通过Hibernate连接到MySQL数据库。该应用程序旨在处理大量数据,约为2,750,000条记录,因此我尽可能地进行了优化。
它运行在我的工作站上,这是一台四核Intel Xeon处理器,配备6GB RAM(1033Mhz),并且在前70k条记录中运行得很好和迅速,完成时间约为15分钟。但到了90k时,它已经花费了约25分钟,变得非常缓慢。
我已经检查了Hibernate代码的计时器,并且发现数据库检索所花费的时间与通常相同。我甚至尝试强制手动垃圾回收,但也不起作用。
相关代码如下:
val recordCount = repo.recordCount
val batchSize = 100
val batches = (0 to recordCount by batchSize).toList
val batchJobs = {
for (batchStart <- batches) yield {
future(new RecordFormatter().formatRecords(new Repo(sessionFactory.openSession),batchStart,batchSize)
}
awaitAll(100000,batchJobs: *_)
在RecordFormatter中(实际上它的命名并不是这样,以防你对我的命名方案感到疯狂),它查询接下来的100个记录,然后再使用开始和结束值之间的between查询来检索实际记录,然后将其作为CSV输出到文本文件中。根据计时器输出,记录格式化程序中的每个操作需要约5秒钟来检索记录,然后需要0.1秒钟将其输出到文件。
尽管如此,一旦减速,它每分钟只处理大约12批100条记录,而当进程首次启动时,它可以处理40批100条记录。
它定期刷新Session,并在每个RecordFormatter运行结束时关闭它(每个RecordFormatter都有自己的会话)。
我主要想了解Scala和Futures的任何已知问题。我注意到当它减速时,它似乎没有使用所有八个可能的线程,这可能可以解释速度下降,但我不明白为什么它会突然停止,而且总是在75000条记录左右。
谢谢!
编辑:更新代码以显示它使用yield和awaitAll,以防这有所区别。
jconsole
($JAVA_HOME/bin/jconsole
) 连接应用程序吗?这非常有助于告诉你一些事情:1. 应用程序是否花费了所有时间来执行 GC?2. 我的线程在做什么? - oxbow_lakes