Should I reuse DatagramPacket?
Asked Answered
V

1

6

I am building a UDP-based application that receives and sends multiple packets.

I could build a new DatagramPacket for each send, or I recycle one instance for the life of my application.

  • Are there any advantages to reusing a DatagramPacket? (e.g. memory-allocation)
  • Are there any potential problems? (e.g. thread-safety)
Voorhis answered 13/10, 2015 at 18:4 Comment(3)
Yes to both. Maybe you'll want to make your question more specific :)Rory
It could work either way. But its definitely safer for threading and internal object consistancy if you create a new one each time. Creating a new one each time is going to add to memory, but all these objects will be new generation and will be cleared by gc, as opposed to a reused DatagramPacket which would end up in old gen mem and thus be harder to clear if/when you're finished with itEastereasterday
I would only consider reusing packets if it's causing issues. You might save time in the encoding process, but caching all of the packets may result in unnecessary complexity, not to mention that you have to keep all of those packets in memory to really save any time.Unflinching
K
3

It looks like you can't. I just tried sending the same DatagramPacket twice and I get the following behavior:

  • The packet is sent only once
  • Netty logs the warning below

So, instead of reusing the DatagramPacket, you can reuse the arguments you pass to the DatagramPacket constructor, mainly the buffer.

2018-10-18 09:29:11.103 WARN 5468 --- [nioEventLoopGroup-2-1] i.n.c.AbstractChannelHandlerContext : Failed to mark a promise as failure because it has failed already: DefaultChannelPromise@748a9b0e(failure: java.lang.IndexOutOfBoundsException: srcIndex: 0), unnotified cause: java.lang.IndexOutOfBoundsException: srcIndex: 0 at io.netty.buffer.UnsafeByteBufUtil.setBytes(UnsafeByteBufUtil.java:519) at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:260) at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1080) at io.netty.channel.nio.AbstractNioChannel.newDirectBuffer(AbstractNioChannel.java:481) at io.netty.channel.socket.nio.NioDatagramChannel.filterOutboundMessage(NioDatagramChannel.java:308) at io.netty.channel.AbstractChannel$AbstractUnsafe.write(AbstractChannel.java:877) at io.netty.channel.DefaultChannelPipeline$HeadContext.write(DefaultChannelPipeline.java:1391) at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738) at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:730) at io.netty.channel.AbstractChannelHandlerContext.access$1900(AbstractChannelHandlerContext.java:38) at io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.write(AbstractChannelHandlerContext.java:1081) at io.netty.channel.AbstractChannelHandlerContext$WriteAndFlushTask.write(AbstractChannelHandlerContext.java:1128) at io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.run(AbstractChannelHandlerContext.java:1070) at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:446) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748)

io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1 at io.netty.buffer.AbstractReferenceCountedByteBuf.release0(AbstractReferenceCountedByteBuf.java:100) ~[netty-buffer-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:84) ~[netty-buffer-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:88) ~[netty-common-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.channel.DefaultAddressedEnvelope.release(DefaultAddressedEnvelope.java:101) ~[netty-transport-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:88) ~[netty-common-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.channel.AbstractChannel$AbstractUnsafe.write(AbstractChannel.java:884) ~[netty-transport-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.write(DefaultChannelPipeline.java:1391) ~[netty-transport-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:738) [netty-transport-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:730) [netty-transport-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext.access$1900(AbstractChannelHandlerContext.java:38) [netty-transport-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.write(AbstractChannelHandlerContext.java:1081) [netty-transport-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext$WriteAndFlushTask.write(AbstractChannelHandlerContext.java:1128) [netty-transport-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.channel.AbstractChannelHandlerContext$AbstractWriteTask.run(AbstractChannelHandlerContext.java:1070) [netty-transport-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) [netty-common-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) [netty-common-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:446) [netty-transport-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) [netty-common-4.1.29.Final.jar!/:4.1.29.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.29.Final.jar!/:4.1.29.Final] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_181]

Katerinekates answered 18/10, 2018 at 7:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.