Netty 4, фатальная ошибка Java 8 JVM (SIGSEGV) - PlatformDependent0.copyMemory - PullRequest
1 голос
/ 14 марта 2019

Я вижу сбой фатальной ошибки JVM с Netty 4.1.34 и Oracle Java 1.8.0_202 (оба последних) при выполнении некоторых (легких) тестов нагрузки. К сожалению, авария не может быть легко воспроизведена - кажется, что это происходит только в 1/10 времени.

Это прокси-сервер HTTP (который также имеет поддержку веб-сокетов), поэтому конвейеры Netty изначально настраиваются с соответствующими кодировщиками / декодерами HTTP (HttpRequestDecoder, HttpResponseEncoder и т. Д.), Но конвейеры изменятся для поддержки декодеров / кодировщиков кадров веб-сокетов, если это применимо (например, как при рукопожатии «Обновление: websocket»).

Первоначально объекты ByteBuf в расширенном / пользовательском обработчике фрейма веб-сокета не были освобождены, что привело к утечке памяти. Но после их выпуска я вижу случайный сбой Java VM:

---------------  T H R E A D  ---------------

Current thread (0x00007f164807d000):  JavaThread "nioEventLoopGroup-4-1" [_thread_in_Java, id=31262, stack(0x00007f163bc9d000,0x00007f163bd9e000)]

Stack: [0x00007f163bc9d000,0x00007f163bd9e000],  sp=0x00007f163bd9b780,  free space=1017k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0xad33a5]  VMError::report_and_die()+0x2e5
V  [libjvm.so+0x4e0444]  report_fatal(char const*, int, char const*)+0x54
V  [libjvm.so+0x9cc815]  SharedRuntime::continuation_for_implicit_exception(JavaThread*, unsigned char*, SharedRuntime::ImplicitExceptionKind)+0x345
V  [libjvm.so+0x918eac]  JVM_handle_linux_signal+0x6bc
V  [libjvm.so+0x90b858]  signalHandler(int, siginfo*, void*)+0x38
C  [libpthread.so.0+0xf6d0]
J 4010 C2 io.netty.util.internal.PlatformDependent0.copyMemory(Ljava/lang/Object;JLjava/lang/Object;JJ)V (35 bytes) @ 0x00007f167ef0b3d2 [0x00007f167ef0b360+0x72]
J 3776 C1 io.netty.buffer.UnsafeByteBufUtil.setBytes(Lio/netty/buffer/AbstractByteBuf;JILio/netty/buffer/ByteBuf;II)V (134 bytes) @ 0x00007f167f65d27c [0x00007f167f65c5a0+0xcdc]
J 3635 C1 io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(ILio/netty/buffer/ByteBuf;II)Lio/netty/buffer/ByteBuf; (16 bytes) @ 0x00007f167f5aeb4c [0x00007f167f5aea40+0x10c]
J 3634 C1 io.netty.buffer.AbstractByteBuf.writeBytes(Lio/netty/buffer/ByteBuf;II)Lio/netty/buffer/ByteBuf; (30 bytes) @ 0x00007f167f5af0dc [0x00007f167f5aef00+0x1dc]
J 4007 C2 io.netty.channel.DefaultChannelPipeline$HeadContext.write(Lio/netty/channel/ChannelHandlerContext;Ljava/lang/Object;Lio/netty/channel/ChannelPromise;)V (12 bytes) @ 0x00007f167f6ca460 [0x00007f167f6ca2a0+0x1c0]
J 3999 C2 io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.run()V (35 bytes) @ 0x00007f167f28d54c [0x00007f167f28d300+0x24c]
J 5000 C2 io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(J)Z (96 bytes) @ 0x00007f167f645b84 [0x00007f167f645600+0x584]
J 4688% C1 io.netty.channel.nio.NioEventLoop.run()V (236 bytes) @ 0x00007f167f0327f4 [0x00007f167f0317c0+0x1034]
j  io.netty.util.concurrent.SingleThreadEventExecutor$5.run()V+44
j  io.netty.util.concurrent.FastThreadLocalRunnable.run()V+4
j  java.lang.Thread.run()V+11
v  ~StubRoutines::call_stub
V  [libjvm.so+0x68839b]  JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*)+0xddb
V  [libjvm.so+0x685c63]  JavaCalls::call_virtual(JavaValue*, KlassHandle, Symbol*, Symbol*, JavaCallArguments*, Thread*)+0x263
V  [libjvm.so+0x686227]  JavaCalls::call_virtual(JavaValue*, Handle, KlassHandle, Symbol*, Symbol*, Thread*)+0x47
V  [libjvm.so+0x6f239c]  thread_entry(JavaThread*, Thread*)+0x6c
V  [libjvm.so+0xa7b9eb]  JavaThread::thread_main_inner()+0xdb
V  [libjvm.so+0xa7bcf1]  JavaThread::run()+0x2d1
V  [libjvm.so+0x90d8c2]  java_start(Thread*)+0x102
C  [libpthread.so.0+0x7e25]

Полный файл hs_err_pid * .log находится на Pastebin .

Что-нибудь очевидное выделяется здесь, пожалуйста? Ранее я использовал устаревшую версию Netty, но обновление до последней версии не помогло (т. Е. У нас все еще возникают сбои).

1 Ответ

1 голос
/ 14 марта 2019

Скорее всего, теперь вы слишком сильно освобождаете объекты ByteBuffer.Скорее всего, вызов PooledUnsafeDirectByteBuf.setBytes выполняет запись в освобожденную память, вызывая сбой.

Именно поэтому в Java есть сборка мусора, и использование прямых байтовых буферов следует обрабатывать с осторожностью.

...