Java 8 来自File.lines()的并行流的内存使用情况

Java 8 来自File.lines()的并行流的内存使用情况,java-8,java-stream,Java 8,Java Stream,我正在使用files.lines()从大文件(8GB+)中读取行。如果按顺序处理,效果会很好,占用的内存非常少。一旦我将parallel()添加到流中,它似乎就会永久挂起它正在处理的数据,最终导致内存不足异常。我相信这是拆分器在尝试拆分时缓存数据的结果,但我不确定。我唯一剩下的想法是使用trySplit方法编写一个自定义拆分器,它可以剥离少量要拆分的数据,而不是试图将文件拆分成一半或更多。还有其他人遇到过这种情况吗?通过代码跟踪我猜是文件使用的拆分器。lines()是拆分器。迭代器拆分器。其tr

我正在使用files.lines()从大文件(8GB+)中读取行。如果按顺序处理,效果会很好,占用的内存非常少。一旦我将parallel()添加到流中,它似乎就会永久挂起它正在处理的数据,最终导致内存不足异常。我相信这是拆分器在尝试拆分时缓存数据的结果,但我不确定。我唯一剩下的想法是使用trySplit方法编写一个自定义拆分器,它可以剥离少量要拆分的数据,而不是试图将文件拆分成一半或更多。还有其他人遇到过这种情况吗?

通过代码跟踪我猜是
文件使用的
拆分器。lines()
拆分器。迭代器拆分器
。其
trySplit()
方法具有以下注释:

        /*
         * Split into arrays of arithmetically increasing batch
         * sizes.  This will only improve parallel performance if
         * per-element Consumer actions are more costly than
         * transferring them into an array.  The use of an
         * arithmetic progression in split sizes provides overhead
         * vs parallelism bounds that do not particularly favor or
         * penalize cases of lightweight vs heavyweight element
         * operations, across combinations of #elements vs #cores,
         * whether or not either are known.  We generate
         * O(sqrt(#elements)) splits, allowing O(sqrt(#cores))
         * potential speedup.
         */
然后,代码看起来像是分成了1024条记录(行)的多个批次。因此,第一次拆分将读取1024行,然后下一次拆分将读取2048行,以此类推。每次拆分将读取越来越大的批次大小

如果您的文件非常大,它最终将达到最大批处理大小33554432,这与dkatzel一样
1。
此问题是由
拆分器.IteratorSplitter
引起的,它将批处理流中的元素。其中批量大小将从1024个元素开始,并增长到33554432个元素


另一个解决方案是使用

上文章中的
FixedBatchSpliteratorBase
,如果您想编写自己的拆分器,这里是一个很好的讨论和出发点,您可以尝试最近的Java 9测试版。它应该有一个更好的可并行化
Files.lines()
实现。再加上关于自定义拆分器和JDK9的注释,我就需要它了。谢谢