Reputation: 1
I simply use the routeguide example in the grpc-java package, and tried to send 1,000,000 message to the server.
for (int i=1; i<=1000000; i++){
requestObserver.onNext(request);
}
I found that the performance is worse and much time is spent on the GC
0.286: [GC (Allocation Failure) [PSYoungGen: 64512K->10237K(74752K)] 64512K->30691K(245760K), 0.0209037 secs] [Times: user=0.10 sys=0.01, real=0.02 secs]
0.335: [GC (Allocation Failure) [PSYoungGen: 65117K->10226K(139264K)] 85570K->80123K(310272K), 0.0369838 secs] [Times: user=0.28 sys=0.01, real=0.04 secs]
0.956: [GC (Allocation Failure) [PSYoungGen: 139250K->10224K(139264K)] 209147K->121117K(310272K), 0.0665830 secs] [Times: user=0.28 sys=0.02, real=0.07 secs]
1.342: [GC (Allocation Failure) [PSYoungGen: 139248K->10208K(268288K)] 250141K->163711K(439296K), 0.0384561 secs] [Times: user=0.24 sys=0.00, real=0.04 secs]
1.380: [Full GC (Ergonomics) [PSYoungGen: 10208K->0K(268288K)] [ParOldGen: 153502K->146307K(303104K)] 163711K->146307K(571392K), [Metaspace: 15761K->15761K(1062912K)], 0.5195652 secs] [Times: user=2.81 sys=0.01, real=0.52 secs]
2.411: [GC (Allocation Failure) [PSYoungGen: 258048K->10208K(268288K)] 404355K->232472K(571392K), 0.0425126 secs] [Times: user=0.26 sys=0.02, real=0.04 secs]
2.978: [GC (Allocation Failure) [PSYoungGen: 268256K->88032K(429056K)] 490520K->315472K(732160K), 0.0456898 secs] [Times: user=0.26 sys=0.05, real=0.04 secs]
3.024: [Full GC (Ergonomics) [PSYoungGen: 88032K->0K(429056K)] [ParOldGen: 227440K->288136K(538624K)] 315472K->288136K(967680K), [Metaspace: 15765K->15765K(1062912K)], 0.4887699 secs] [Times: user=3.11 sys=0.02, real=0.49 secs]
Sep 21, 2018 1:40:16 PM routeguide.RouteGuideClient info
INFO: Finished RouteChat
Heap
PSYoungGen total 429056K, used 331100K [0x000000076cf80000, 0x000000078ee80000, 0x00000007c0000000)
eden space 340992K, 97% used [0x000000076cf80000,0x00000007812d7330,0x0000000781c80000)
from space 88064K, 0% used [0x0000000788200000,0x0000000788200000,0x000000078d800000)
to space 103936K, 0% used [0x0000000781c80000,0x0000000781c80000,0x0000000788200000)
ParOldGen total 538624K, used 288136K [0x00000006c6e00000, 0x00000006e7c00000, 0x000000076cf80000)
object space 538624K, 53% used [0x00000006c6e00000,0x00000006d87620b0,0x00000006e7c00000)
Metaspace used 15976K, capacity 16234K, committed 16384K, reserved 1062912K
class space used 1902K, capacity 1989K, committed 2048K, reserved 1048576K
Any way to improve the performance base on the routeguide example?
Upvotes: 0
Views: 460
Reputation: 6628
The issue with the code is it is not honoring the flow control of the server. You need to cast the observer to a CallStreamObserver. Then, you can call isReady()
to check if the server can accept more messages before sending another. If the server is not ready, isReady()
will return false, and you will need to wait until it is. You can do this by calling setOnReadyHandler()
on the call stream observer, which will notify you when you can send again.
The reason is that gRPC will buffer your messages in memory if the server cannot accept more. Normally this isn't a problem, because most users just send one message. However, when sending a lot of messages, they will fill up memory on the client side and cause the OOM you see. The gRPC API is designed to be non blocking, so the onNext()
call will not wait for the server to be ready. If it did, there would be a risk of a deadlock.
Upvotes: 1