DKS*_*ore 4 java api performance berkeley-db filereader
在我工作的地方,曾经有过每个文件超过百万行的文件.即使服务器内存超过10GB,8GB用于JVM,有时服务器会被暂停一段时间并扼杀其他任务.
我对代码进行了分析,发现虽然文件读取内存使用频繁增加千兆字节(1GB到3GB)然后突然恢复正常.似乎这种频繁的高内存和低内存使用会挂起我的服务器.当然这是由于垃圾收集.
我应该使用哪个API来读取文件以获得更好的性能?
现在我正在使用BufferedReader(new FileReader(...))读取这些CSV文件.
过程:我如何阅读文件?
更新
我这样读取30或31个文件(一个月的数据)并将符合条件存储在地图中.后来这张地图用于在不同的表格中获得一些罪魁祸首.因此必须读取并存储该数据.虽然我现在已经将HashMap部分切换到BerkeleyDB但是在读取文件时的问题是相同甚至更糟.
Car*_*icz 10
BufferedReader是用于此目的的两个最佳API之一.如果您真的遇到文件读取问题,可以选择使用NIO中的内容来存储映射文件,然后直接从内存中读取内容.
但你的问题不在于读者.您的问题是每次读取操作都会创建一堆新对象,最有可能是您刚读完后所做的事情.
您应该考虑清理输入处理,着眼于减少您创建的对象的数量和/或大小,或者只是在不再需要时更快地删除对象.是否可以一次处理一行或一块文件而不是将整个内容吸入内存进行处理?
另一种可能性是摆弄垃圾收集.你有两种机制:
每隔一段时间显式调用一次垃圾收集器,比如每10秒或每1000条输入线或其他东西.这将增加GC完成的工作量,但每个GC需要的时间更少,内存不会膨胀太多,因此希望对服务器其余部分的影响更小.
摆弄JVM的垃圾收集器选项.这些在JVM之间有所不同,但java -X应该给你一些提示.
更新:最有希望的方法:
您是否真的需要内存中的整个数据集进行处理?
我对代码进行了分析,发现虽然文件读取内存使用频繁增加千兆字节(1GB到3GB)然后突然恢复正常.似乎这种频繁的高内存和低内存使用会挂起我的服务器.当然这是由于垃圾收集.
使用BufferedReader(new FileReader(...))不会导致这种情况.
我怀疑问题是你正在读取数组或列表中的行/行,处理它们然后丢弃数组/列表.这将导致内存使用量增加然后再次减少.如果是这种情况,您可以通过在读取时处理每一行/每行来减少内存使用量.
编辑:我们同意问题是关于用于表示内存中文件内容的空间.巨大的内存哈希表的替代方法是回到我们在以千字节为单位测量计算机内存时使用的旧"排序合并"方法.(我假设处理由一个步骤决定,你用键K进行查找以获得相关的行R.)
如有必要,预处理每个输入文件,以便可以在密钥K上对它们进行排序.
使用有效的文件排序实用程序将所有输入文件按顺序排序到K.您希望使用将使用经典合并排序算法的实用程序.这会将每个文件拆分为较小的块,这些块可以在内存中排序,对块进行排序,将它们写入临时文件,然后合并已排序的临时文件.UNIX/Linux sort实用程序是一个不错的选择.
并行读取已排序的文件,从所有文件中读取与每个键值相关的所有行,处理它们,然后单步执行下一个键值.
实际上,使用BerkeleyDB没有帮助我有点惊讶.但是,如果分析告诉您构建数据库的时间很长,那么在构建数据库之前,您可以通过将输入文件(如上所述!)排序为升序键来加快速度.(创建基于文件的大型索引时,如果按键顺序添加条目,则会获得更好的性能.)