grpc-java
リモート呼び出しを処理するために、バージョン 0.8.0 サーバーを実行しています。サーバーのロジックは非常に単純で、指定された ID で指定されたデータを DB から取得してredis
キャッシュに設定するだけです。
JVM 引数は として設定され-Xss256k -Xmx8G
ます。JVM は、サーバーが起動するとすぐに 4 GB (RES 内top
) のメモリを使用し、約 400 QPS を処理しました。jmap コマンドを発行jmap -histo:live <pid>
し、次のダンプ ファイルを取得しました。
num #instances #bytes class name
----------------------------------------------
1: 4998400 119961600 io.netty.buffer.PoolThreadCache$MemoryRegionCache$Entry
2: 212415 23503536 [B
3: 11076 20170816 [Lio.netty.buffer.PoolThreadCache$MemoryRegionCache$Entry;
4: 70853 10010904 [C
5: 28819 2518640 [Lio.netty.util.Recycler$DefaultHandle;
6: 31232 1998848 com.mysql.jdbc.ConnectionPropertiesImpl$BooleanConnectionProperty
7: 7287 1764136 [I
8: 70000 1680000 java.lang.String
9: 45766 1464512 java.util.Hashtable$Entry
10: 134 1291992 [D
11: 14376 1265088 io.netty.buffer.PooledUnsafeDirectByteBuf
12: 5527 1160200 [Ljava.util.HashMap$Node;
13: 16340 1116584 [[B
io.netty.buffer.PoolThreadCache$MemoryRegionCache$Entry
そこから、約 100MB のメモリを使用する膨大な数のインスタンスがあることがわかりました。grpc
( を通信層として使用していることに注意してくださいnetty
。) これは異常のようです。それでも、ヒープ内オブジェクトは 4GB のメモリを占有できませんでした。これは、netty
.
ヒープ外のメモリ リークはありましたか?
なぜこれが起こるのでしょうか?そして、この問題を解決または診断する方法は?