Я заметил, что моя программа имеет серьезную утечку памяти (потребление памяти увеличивается). Мне пришлось распараллелить эту задачу NLP (используя StanfordNLP EnglishPCFG Parser и Tregex Matcher). Итак, я построил пайплайн актеров (всего 6 актеров на каждую задачу):
val listOfTregexActors = (0 to 5).map(m => system.actorOf(Props(new TregexActor(timer, filePrinter)), "TregexActor" + m))
val listOfParsers = (0 to 5).map(n => system.actorOf(Props(new ParserActor(timer, listOfTregexActors(n), lp)), "ParserActor" + n))
val listOfSentenceSplitters = (0 to 5).map(j => system.actorOf(Props(new SentenceSplitterActor(listOfParsers(j), timer)), "SplitActor" + j))
Мои актеры довольно стандартны. Им нужно остаться в живых, чтобы обработать всю информацию (по пути нет ядовитых таблеток). Потребление памяти растет и растет, и я понятия не имею, что не так. Если бы я запускал однопоточность, потребление памяти было бы в порядке. Я где-то читал, что если актеры не умрут, внутри ничего не выйдет. Должен ли я вручную выпускать вещи?
Есть два тяжеловесных актера:
https://github.com/windweller/parallelAkka/blob/master/src/main/scala/blogParallel/ParserActor.scala https://github.com/windweller/parallelAkka/blob/master/src/main/scala/blogParallel/TregexActor.scala
Интересно, может ли это быть закрытие Scala или другой механизм, который сохраняет слишком много информации, и GC не может как-то ее собрать.
Вот часть TregexActor:
def receive = {
case Match(rows, sen) =>
println("Entering Pattern matching: " + rows(0))
val result = patternSearching(sen)
filePrinter ! Print(rows :+ sen.toString, result)
}
def patternSearching(tree: Tree):List[Array[Int]] = {
val statsFuture = search(patternFuture, tree)
val statsPast = search(patternsPast, tree)
List(statsFuture, statsPast)
}
def search(patterns: List[String], tree: Tree) = {
val stats = Array.fill[Int](patterns.size)(0)
for (i <- 0 to patterns.size - 1) {
val searchPattern = TregexPattern.compile(patterns(i))
val matcher = searchPattern.matcher(tree)
if (matcher.find()) {
stats(i) = stats(i) + 1
}
timer ! PatternAddOne
}
stats
}
Или, если мой код проверяется, может ли это быть утечка памяти синтаксического анализатора StanfordNLP или сопоставителя tregex ?? Существует ли стратегия ручного освобождения памяти или мне нужно убить этих акторов через некоторое время и назначить задачи их почтовых ящиков новому актору для освобождения памяти? (Если да, то как?)
После некоторой борьбы с инструментами профилирования я наконец смог использовать VisualVM с IntelliJ. Вот снимки. GC никогда не запускался.
Другой - Heap Dump:
Резюме конвейера:
Необработанные файлы -> Актеры SentenceSplit (6) -> Актеры парсера (6) -> Актеры Tregex (6) -> Актеры вывода файла (сделано)
Шаблоны определены в файле Entry.scala: https://github.com/windweller/parallelAkka/blob/master/src/main/scala/blogParallel/Entry.scala
regexPattern
иlexparser
занимали много памяти (хотя и не так много, какfloat[]
). Они принадлежатTregexActor
иParserActor
. Также GC никогда не запускался. - person windweller   schedule 28.12.2014float[]
в своем коде... - person windweller   schedule 28.12.2014patternFuture
иpatternsPast
? Можете ли вы кратко изложить свой конвейер, т. Е. Какой участник отправляет какое сообщение какому другому участнику в цепочке? - person Soumya Simanta   schedule 28.12.2014patternFuture
иpatternPast
определены в файлеEntry.scala
здесь: github.com/windweller/parallelAkka/blob/master/src/main/scala/. Хотя я сомневаюсь, что дело в этом. - person windweller   schedule 28.12.2014float[]
получено отExhaustivePCFGParser
, что означает, что это от Parser Actor. Но что я могу сделать с этой информацией?? - person windweller   schedule 28.12.2014