akka / akka-grpc

Akka gRPC
https://doc.akka.io/docs/akka-grpc/
Other
431 stars 123 forks source link

Memory churn in marshalling infrastructure #1364

Open jrudolph opened 3 years ago

jrudolph commented 3 years ago

Marshallings reliance on moving data between InputStream / OutputStream leads to a lot of memory churn while supplying the intermediate buffers.

I haven't looked deeply into it yet but it seems that this is caused by having to go to some io.grpc abstractions. Do we have any idea how we could avoid that?

--- 2912446648 bytes (12.77%), 5819 samples
  [ 0] byte[]
  [ 1] akka.grpc.internal.BaseMarshaller.parse
  [ 2] akka.grpc.internal.Marshaller.parse
  [ 3] akka.grpc.internal.Marshaller.parse
  [ 4] io.grpc.MethodDescriptor.parseResponse
  [ 5] io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInternal
  [ 6] io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInContext
  [ 7] io.grpc.internal.ContextRunnable.run
  [ 8] io.grpc.internal.SerializingExecutor.run
  [ 9] akka.dispatch.TaskInvocation.run
  [10] akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec
  [11] java.util.concurrent.ForkJoinTask.doExec
  [12] java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec
  [13] java.util.concurrent.ForkJoinPool.scan
  [14] java.util.concurrent.ForkJoinPool.runWorker
  [15] java.util.concurrent.ForkJoinWorkerThread.run
lomigmegard commented 3 years ago

You mean the byte array allocated in BaseMarshaller to read from the InputStream (only API provided by io.grpc.MethodDescriptor) ? Might be linked to this PR: https://github.com/akka/akka-grpc/pull/1318/files#diff-1a02adbd4ed9c032022756fe7dbbac1e967816613c7f1adef4f3e2330136fa11L22

Actually I didn't see but there is an alternative solution in https://github.com/akka/akka-grpc/pull/1378 (still relying on internal buffering of the stream)

jrudolph commented 3 years ago

Thanks, @lomigmegard, those are relevant indeed.