2012-08-13 2 views
2

직장에서 일부 Clojure 코드를 스트레스 테스트 할 때 큰 데이터 세트를 반복 할 때 힙 공간이 부족한 것으로 나타났습니다. 나는 결국 Clojure의 doseq 함수와 지연 형 시퀀스의 조합으로이 문제를 추적 할 수있었습니다.간단한 게으른 seq에 대한 doseq에 힙 공간이 부족합니다.

이 가능한 힙 공간을 소진하여 Clojure의 충돌 최소한의 코드입니다 :

(doseq [e (take 1000000000 (iterate inc 1))] (identity e)) 

doseq에 대한 문서는 명확하게 게으른 시퀀스의 머리를 유지하지 않기 때문에, 나는를 기대한다고 위 코드의 메모리 복잡성은 O (1)에 가깝습니다. 내가 빠진 것이 있습니까? doseq이 작업에 적합하지 않다면 매우 큰 게으른 시퀀스를 반복하는 Clojure-idiomatic 방식은 무엇입니까?

+7

? OSX에서 clojure 1.4/java 1.6.0_33을 사용하여 깨끗한 repl에서 해당 코드를 실행하면 400Mb 아래에서 완전히 정적 인 메모리 사용이 표시됩니다. –

+1

문제를 일으키는 정확한 스 니펫이 확실합니까? 내 컴퓨터에서 잘 돌아 간다 (Clojure 1.4, JDK7, Windows, Eclipse/CCW). 어떻게 든 시퀀스 헤드를 잡고 있다면 문제가 될 수 있습니다. if (iterate inc 1)가 다른 곳에 저장되었습니다. – mikera

+0

당신이 맞습니다. Leiningen 2가 REPL (역사, 키 네비게이션 등)에 추가하는 것들을 끄고 바닐라 Clojure 1.4를 사용하면 문제가 사라집니다. 감사. – the80srobot

답변

2

이 샘플을 실행할 때 메모리 사용량이 2.0 기가에 도달 했으므로 실제로 램이 부족한 것 같습니다.

그것은 확실히 실행하는 데 시간이 걸릴 않습니다

user=> (time (doseq [e (take 1000000000 (iterate inc 1))] (identity e))) 
"Elapsed time: 266396.221132 msecs" 

폼 상단 : Clojure의 버전과 자바 런타임은 당신이 어떤을 사용하는

23999 arthur 20 0 4001m 1.2g 5932 S 213 15.3 17:11.35 java           
24017 arthur 20 0 3721m 740m 5548 S 88 9.3 13:49.95 java 
관련 문제