Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在使用steam并行的计算时候,出现了oom #8

Open
xueding-e opened this issue Dec 16, 2019 · 4 comments
Open

在使用steam并行的计算时候,出现了oom #8

xueding-e opened this issue Dec 16, 2019 · 4 comments

Comments

@xueding-e
Copy link

感谢您的科普,我也顺利用上了流。
在实际使用并行流的时候遇到了一个oom。
大致情况是要处理一个四十多m的txt文件,内容为换行的字符串。
使用lines.flatMap(line -> Arrays.stream(line.split(" "))).parallel().distinct().count();做并发计算词语个数(数量大概在三百万,类似
一@一对一 5
一@一道 5
一@丁 6
一@七旬 8
一@万 157)。
执行期间,并行流吃光了我的内存,cpu,我jvm中的old跟eden全部爆满,方法区正常,线程正常。
串行与外部迭代只会吃掉五十m内存。

请教作者,是我并发流用的不对,还是jdk8的流有bug ---下面是重现代码
static void useStream(){
long uniqueWord = 0;
try (Stream lines =
Files.lines(Paths.get("D:\nlp\dictionary\CoreNatureDictionary.ngram.txt"), Charset.defaultCharset())){
long start = System.currentTimeMillis();
uniqueWord = lines.flatMap(line -> Arrays.stream(line.split(" "))).parallel().distinct().count();
// uniqueWord = lines.flatMap(line -> Arrays.stream(line.split(" "))).distinct().count();
System.out.println(uniqueWord);
long end = System.currentTimeMillis();
System.out.println("耗时"+ (end-start)+"ms");
}catch (IOException e){
e.printStackTrace();
}
}

@xueding-e
Copy link
Author

这是缩减后的文件,只有10m,依旧会引起我2g jvm的oom
CoreNatureDictionary.ngram.txt

@xueding-e xueding-e changed the title 我在使用steam并行的时候,出现了oom 在使用steam并行的计算时候,出现了oom Dec 16, 2019
@vincentruan
Copy link

像是forkjoin导致内存复制的原因,建议直接输出forkjoin线程池内各内存分布看一下,应该就清楚原因了

@xueding-e
Copy link
Author

像是forkjoin导致内存复制的原因,建议直接输出forkjoin线程池内各内存分布看一下,应该就清楚原因了

这样并行流不能用了哦,200倍的内存都吃完了

@xiajiafu
Copy link
Contributor

xiajiafu commented Oct 9, 2020

这样并行流不能用了哦,200倍的内存都吃完了
通过运行你的代码,我这边(jdk版本是1.8.0_144)设置的jvm参数:-Xmx1024m -Xms1024m,发现是能运行成功得出结果的,多次运行平均耗时5000~6000ms,但是串行流的时间只有它的十分之一。按照我的理解,并行流的使用场景是CPU密集型的,你这个场景应该是不太适用。测试代码如下:
public static void main(String[] args) { long uniqueWord; Path path = Paths.get("C:\\Users\\DELL\\Downloads\\CoreNatureDictionary.ngram.txt"); try (Stream<String> lines = Files.lines(path, Charset.defaultCharset())) { long start = System.currentTimeMillis(); uniqueWord = lines.flatMap(line -> Arrays.stream(line.split(" "))).parallel().distinct().count(); // uniqueWord = lines.flatMap(line -> Arrays.stream(line.split(" "))).distinct().count(); System.out.println(uniqueWord); long end = System.currentTimeMillis(); System.out.println("耗时" + (end - start) + "ms"); } catch (IOException e) { e.printStackTrace(); } }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants