Ci sono due problemi qui, la quantità di memoria richiesta per memorizzare una raccolta parallela e la quantità di memoria richiesta per "passare attraverso" una raccolta parallela.
La differenza può essere visto tra queste due linee:
(1 to 1000000).map(_+3).toList
(1 to 1000000).par.map(_+3).toList
Il REPL memorizza le espressioni valutate, ricordo. Sul mio REPL, posso eseguire entrambe queste 7 volte prima di esaurire la memoria. Passare attraverso le esecuzioni parallele utilizza temporaneamente memoria extra, ma una volta eseguita la lista, quell'utilizzo extra viene eliminato.
(1 to 100000).par.map(_+3)
restituisce un ParSeq [Int] (in questo caso un ParVector), che occupa più spazio di un vettore normale.Questo ho può eseguire 4 volte prima ho esaurito la memoria, che posso eseguire questo:
(1 to 100000).map(_+3)
11 volte prima ho esaurito la memoria. Quindi le raccolte parallele, se le mantieni in giro occuperanno più spazio.
Per ovviare al problema, è possibile trasformarli in raccolte più semplici come un List
prima di restituirli.
Per quanto riguarda il motivo per cui così tanto spazio è occupato da collezioni parallele e perché mantiene i riferimenti a tante cose, non so, ma ho il sospetto views
[*], e se pensate che sia un problema, raise an issue for it.
[*] senza alcuna prova reale.
fonte
2012-06-01 12:13:18
Potete aggiungere qualche dettaglio in più qui? Con quanta memoria si avvia la JVM, nessun altro switch? Esegui questo nel REPL o lo compili? Se esegui questo dal REPL quante istruzioni hai eseguito prima? L'ho appena provato nel mio REPL e l'ho eseguito 10 volte senza una OOM. – drexin
Funziona bene nel mio REPEL a. – Jan
@Jan per me ha funzionato bene anche nel REPL, ma solo la prima volta ... – Christian