У меня есть веб-сервер, который принимает входящее соединение через веб-сокет, реализованный с помощью akka http в Scala.Тем не менее, я наблюдаю монотонное увеличение использования памяти моего приложения.После долгого копания я обнаружил, что некоторые внутренние объекты Akka создаются для каждого соединения, но не очищаются после отключения клиента.Специально этот класс: akka.stream.impl.fusing.ActorGraphInterpreter
.Один новый такой объект создается для каждого соединения.Я использовал jmap
для подсчета количества объектов, команда приведена ниже.Я не уверен, что делаю что-то не так здесь.Любой совет будет высоко ценится.
У меня есть супер простой эхо-сервер веб-сокета, чтобы повторить это наблюдение:
package samples
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.ws.{Message, TextMessage}
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Flow, Source}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.io.StdIn
object AkkaWsExample {
implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
private val greeterWebSocketService = {
Flow[Message]
.collect {
case tm: TextMessage =>
println(s"Received $tm")
TextMessage(Source.single("Hello ") ++ tm.textStream)
}
}
def main(args: Array[String]): Unit = {
//#websocket-routing
val route =
path("greeter") {
get {
handleWebSocketMessages(greeterWebSocketService)
}
}
val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)
println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
StdIn.readLine() // for the future transformations
bindingFuture
.flatMap(_.unbind()) // trigger unbinding from the port
.onComplete(_ => system.terminate()) // and shutdown when done
}
}
Затем я использовал любой метод для подключения к этому серверу и отключения, и запуститьjmap для подсчета количества объектов и обнаружения строго 1 нового объекта для каждого соединения.Я попробовал это и с тысячами соединений, происходит то же самое.
Я использовал эту команду для подсчета количества объектов:
jmap -histo: live [pid] |grep ActorGraphInterpreter
Вот результаты при запуске и после открытия и закрытия 1000 подключений
ip-192-168-30-10: ~ liuh $ jps |Греп Акка |awk '{print $ 1}' |xargs jmap -histo: live |grep ActorGraphInt |head -n1
701: 1 56 akka.stream.impl.fusing.ActorGraphInterpreter
ip-192-168-30-10: ~ liuh $ jps |Греп Акка |awk '{print $ 1}' |xargs jmap -histo: live |grep ActorGraphInt |head -n1
119: 1001 56056 akka.stream.impl.fusing.ActorGraphInterpreter
Вы можете видеть, что количество объектов увеличилось строго на числосоединения.Я удостоверился, что моя клиентская сторона отключена - я закрыл процессы и также подтвердил с помощью netstat
, что соединения были закрыты.