Java中哪种API用于文件读取以获得最佳性能?
在我工作的地方,以前每个文件都有超过百万行的文件。尽管服务器内存超过10GB,JVM为8GB,但有时服务器会挂起一会儿,并阻塞其他任务 我分析了代码,发现当文件读取内存使用频繁增加(1GB到3GB),然后突然恢复正常时。这种频繁的高内存和低内存使用似乎挂起了我的服务器。当然,这是由于垃圾收集 我应该使用哪个API来读取文件以获得更好的性能 现在我正在使用Java中哪种API用于文件读取以获得最佳性能?,java,performance,api,berkeley-db,filereader,Java,Performance,Api,Berkeley Db,Filereader,在我工作的地方,以前每个文件都有超过百万行的文件。尽管服务器内存超过10GB,JVM为8GB,但有时服务器会挂起一会儿,并阻塞其他任务 我分析了代码,发现当文件读取内存使用频繁增加(1GB到3GB),然后突然恢复正常时。这种频繁的高内存和低内存使用似乎挂起了我的服务器。当然,这是由于垃圾收集 我应该使用哪个API来读取文件以获得更好的性能 现在我正在使用BufferedReader(新文件阅读器(…)来读取这些CSV文件 过程:我如何读取文件 我逐行阅读文件 每行有几列。根据类型,我相应地解析它
BufferedReader(新文件阅读器(…)
来读取这些CSV文件
过程:我如何读取文件
BufferedReader(新文件读取器(…)
不会导致这种情况
我怀疑问题在于您正在将行/行读入数组或列表,处理它们,然后丢弃数组/列表。这将导致内存使用量先增加,然后再次减少。如果是这种情况,您可以通过在读取每一行时处理每一行来减少内存使用
编辑:我们一致认为问题在于内存中用于表示文件内容的空间。一个巨大的内存哈希表的替代方法是回到旧的“排序合并”方法,我们在计算机内存以KB为单位进行测量时使用了这种方法。(我假设处理由一个步骤控制,在该步骤中,您使用键K进行查找,以获得关联的行R。)
sort
实用程序是一个不错的选择事实上,我有点惊讶使用BerkeleyDB没有帮助。但是,如果分析告诉您大部分时间都在构建数据库,那么您可以通过在构建数据库之前将输入文件(如上!)按升序排序来加快它的速度。(创建大型基于文件的索引时,如果按键顺序添加条目,则性能会更好。)BufferedReader是用于此目的的两个最佳API之一。如果您在读取文件时确实遇到问题,另一种方法可能是使用内存中的内容映射文件,然后直接从内存中读取内容 但你的问题不在于读者。你的问题是每次读取操作都会创建一堆新对象,最有可能是在读取后所做的事情 你应该考虑清理输入处理,注意减少所创建的对象的数量和/或大小,或者只是简单地在不再需要的时候快速清除对象。是否有可能一次只处理一行或一块文件,而不是将整个文件吸入内存进行处理 另一种可能是处理垃圾收集。您有两种机制:
- 每隔一段时间显式地调用垃圾收集器一次,比如说每10秒或每1000行输入或其他。这将增加GC所完成的工作量,但每个GC所花费的时间较少,内存不会膨胀太多,因此希望对服务器其余部分的影响较小
- 摆弄JVM的垃圾收集器选项。这些在JVM之间有所不同,但是
应该给您一些提示java-X
您真的需要一次在内存中处理整个数据集吗?尝试使用以下vm选项来调整gc(并进行一些gc打印):
有益的评论。我已经在内存超过某个阈值时调用了GC,但这似乎对我没有帮助。您指出对象创建是罪魁祸首。可能是。正如我在stack trace中看到的一些BigDecimal类以及我创建的类一样。如果配置文件中有您以前不知道的数据类型,那么您很可能正在使用第三方库。可能是内存泄漏的罪魁祸首!不,一点也不。我使用的是整型、长型、双精度、文件、文件读取器、BufferedReader、line.split('\t',-1)、Map、HashMap以及Java标准库中的所有内容。我使用自己的类键和数据,每个类有4个变量。我按键聚合数据并将它们存储在HashMap中。显式GC是个坏主意。但是-XX:+DisableExplicitGC将删除该p
-verbose:gc -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+PrintGCDetails -XX:+PrintGCTimeStamps