2012-10-16 3 views
3

나는 병렬로 처리하려고하는 xml 파일을 가지고있다. 미래를 사용하는 나의 스칼라 코드 (2.9.2)는 정상적으로 시작하지만 내 컴퓨터에있는 32G의 거의 100 %를 차지합니다. 이 작업을 순차적으로 수행하면 이런 일이 발생하지 않으므로 내 생각에 스칼라 선물 사용시 가비지 수집에 문제가있는 것입니다.스칼라 미래의 가비지 컬렉션

다음은 제 코드를 제거한 것입니다. 누가 잘못되었는지 말해 줄 수 있니?

val filenameGroups = someStringListOfFilepaths.grouped(1000).toStream 
val tasks = filenameGroups.map { 
    fg => 
    scala.actors.Futures.future { 
     val parser = new nu.xom.Builder() // I'm using nu.xom. Not sure it matters. 
     fg.map { 
     path => { 
      val doc = parser.build(new java.io.File(path)) 
      val result = doc.query(some xpath query) 
      result 
     } 
     }.toList 
    } 
} 

val pairs = tasks.par.flatMap(_.apply) 

이메일 : 알았어, 내가 해결 했어.하지만 왜 이것이 차이가 나는지 아직도 모르겠다.

내부 루프의 대부분의 코드를 추출한 다음 다시 작성합니다. 그리고 미래의 파서 인스턴스화를 꺼 냈습니다. 현재 메모리 사용량은 17 %로 평평하게 유지됩니다. 아무도 이것이 왜 차이를 만들지 어떤 생각을 가지고 있습니까? 여기

내가 무슨 짓을했는지의 단순화 된 버전입니다 :

def process(arglist...) = yada 

val tasks = filenameGroups.map { 
    fg => 
    val parser = new nu.xom.Builder() 
    scala.actors.Futures.future { 
     process(fg, parser) 
    } 
} 

val pairs = tasks.par.flatMap(_.apply) 
+0

얼마나 많은 파일을 동시에 처리 하시겠습니까? 너는 그것들 중 적어도 수천이있는 것 같아. 수천 개의 XML 파일을 메모리에로드하면 전체 RAM이 빠르게 소모됩니다. 이 작업을 순차적으로 수행하면 기본적으로 파일을 읽고 처리하며 가비지 수집에 적합합니다. –

+0

@TomaszNurkiewicz 최대한 많은 수의 파일을 처리하고 200,000 개의 파일이 있습니다. 나는 단지 스칼라 미래가 현명 할 것이고 오직 8 개의 (또는 당신이 가진 많은 프로세서가) 미래의 인스턴스를 생성 할 것이라고 생각했기 때문에 나는 한 번에 8 개의 XML 문서만을 메모리에 가지고있다. – JasonMond

답변

2

선물은 정말 당신이 원하는 얼마나 많은 스레드를 예측할 수 또는 계산이 소요됩니다 얼마나 많은 메모리, 그래서 적절하게 직렬화 계산을 넣어 일반적으로 귀하의 책임입니다 겸손한 수의 선물 안에. 특히, 8 코어 머신을 사용하는 경우, someStringListOfFilepaths.length/8보다 훨씬 작은 그룹을 그룹화하지 않을 것입니다 (파일이 너무 커서 메모리를 한 번에 8 개까지 가질 수없는 경우는 더 적음). 생각할 필요없이 컴퓨터 당 크기를 조정하려는 경우 코어 수인 covered on SO 및 기타 여러 위치를 검사하는 표준 Java 트릭을 사용할 수 있습니다. (이 경우에도 Runtime.getRuntime.maxMemory을 검사하고 싶을 수도 있습니다. 많은 코어와 많은 RAM이 있거나 VM에 많이 할당되지 않은 머신에있는 경우를 대비하여).

(부수적으로, 최소한의 예제 게으름과 선물이 있지만 게으름은 당신을 위해 아무 것도하지 않습니다. 선물은 이미 만들어져있을 때 실행되지 않으므로 미래의 인스턴스 생성을 지연하면 아마도 도움이되지 않을 것입니다.)

당신은 200k 파일을 가지고 있고, 200k 결과로 끝날 것이고, 결과가 얼마나 큰지에 따라, 그것은 많은 메모리를 먹을 수 있습니다. 아마도 32G가 아니 겠지만 누가 파일에 무엇이 있는지 알고 있습니까?

+0

이 코드를 순차적으로 실행했지만 메모리 사용량이 5 %를 초과하지 않습니다. 또한 귀하의 추천에 따라 그룹 크기를 30K로 올리려고했습니다. 그것은 여전히 ​​거의 100 % 메모리 사용을 치는 결과를 초래합니다. – JasonMond

+0

@ JasonMond - 한 그룹의 모든 파일을 실행하면 어떨까요? 즉, 결국 순차적이지만 미래에 포장 된 경우에는 어떻게 될까요? 평행선과 미래가 붉은 청어인지 궁금합니다. 실제로 그룹화 된 스트림을 사용하는 fg.map에 대한 것이죠? –

+1

스트림이 암기되어 있고 그는 머리에 대한 참조를 유지하고 있지 않습니까 (작업) –

관련 문제