2014-05-08 22 views
1

这是我的服务器端代码。此代码在netty的帮助下读取udp流量。但是,有时我有一个错误....我无法修复它....这是很悲哀...LEAK:ByteBuf.release()在垃圾回收之前未被调用

@Override 
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { 
     ByteBuf bb = msg.content(); 
     RoomController roomController = RoomController.getInstance(); 
     try 
     { 
     int opcode = bb.readUnsignedByte(); 
     byte slot = bb.readByte(); 
     byte[] ignore = new byte[8]; 
     bb.readBytes(ignore); 
     int accountId = bb.readUnsignedByte(); 
     switch(opcode) 
     { 
     case 65: { 
      log.info("Try connect player " + msg.sender().getAddress() + ":" + msg.sender().getPort()); 
      Player player = roomController.getPlayer(msg.sender().getAddress()); 
      if(player != null) { 
      ByteBuffer _buffer = new ByteBuffer(); 
      _buffer.writeC((byte) 66); 
      _buffer.writeC((byte) 0); 
      _buffer.writeB(new byte[5]); 
      _buffer.writeC((byte) 0x0b); 
      _buffer.writeB(new byte[3]); 
      player.playerPort = msg.sender().getPort(); 
      log.info("Send accept data! " + msg.sender().getAddress().toString() + ":" + msg.sender().getPort()); 
      ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(_buffer.getData(), 0, _buffer.getData().length), msg.sender())); 
      } 
      break; 
     } 
     //case (byte) 131: 
     //case (byte) 132: 
     //case 84: 
     //case 97: 
     case 131: 
     case 132: 
     case 4: 
     case 3: { 
      Player player = roomController.getPlayer(msg.sender().getAddress()); 
      if(player != null) { 
      if(player.isActive) { 
      if(player.isHost) { 
      for(Player players : roomController.getPlayersForIP(player.roomID).values()) { 
       if(!players.isHost && players.playerPort > 0) { 
       ctx.writeAndFlush(new PBUDPServerPacket(opcode, Unpooled.copiedBuffer(msg.content()), new InetSocketAddress(players.playerIP, players.playerPort), (byte)slot, ignore, accountId).getPacket()); 
       } 
      } 
      } else { 
      Player host = roomController.getHostForIP(player.roomID); 
      if(host.playerPort > 0) { 
       ctx.writeAndFlush(new PBUDPServerPacket(opcode, Unpooled.copiedBuffer(msg.content()), new InetSocketAddress(host.playerIP, host.playerPort), (byte)slot, ignore, accountId).getPacket()); 
      } 
      } 
      } 
      } 
      break; 
     } 
     case 97: { 
      log.info("opcode: " + opcode + " sender: " + msg.sender().getAddress().getHostAddress()); 
      ctx.writeAndFlush(new PBUDPServerPacket(opcode, Unpooled.copiedBuffer(msg.content()), new InetSocketAddress(msg.sender().getAddress(), msg.sender().getPort()), (byte)slot, ignore, accountId).getPacket()); 
      break; 
     } 
     case 67: { 
      log.info("try remove player " + msg.sender().getAddress().toString()); 
      RoomController.getInstance().removePlayer(msg.sender().getAddress()); 
      break; 
     } 
     default: { 
      log.warn("unknown opcode: " + opcode); 
     } 

     } 
     } 
     catch(Exception e) { 
     log.error(e.toString()); 
     } 
     finally { 
     bb.clear(); 
     } 
    } 

错误:

[18:16:46|ERROR|nioEventLoopGroup-2-1 |io.netty.util.ResourceLeakDetector    ] LEAK: ByteBuf.release() was not called before it's garbage-collected. 

如何修复错误? ?这对我来说非常重要。

堆栈跟踪:

[17:14:59|ERROR|nioEventLoopGroup-2-1 |io.netty.util.ResourceLeakDetector    ] LEAK: ByteBuf.release() was not called before it's garbage-collected. 
Recent access records: 1 
#1: 
io.netty.buffer.AdvancedLeakAwareByteBuf.writeBytes(AdvancedLeakAwareByteBuf.java:559) 
io.netty.buffer.Unpooled.copiedBuffer(Unpooled.java:421) 
ru.pb.battle.network.client.BattleClientConnection.channelRead0(BattleClientConnection.java:89) 
ru.pb.battle.network.client.BattleClientConnection.channelRead0(BattleClientConnection.java:42) 
io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) 
io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) 
io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) 
io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) 
io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:93) 
io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:485) 
io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:452) 
io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:346) 
io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) 
java.lang.Thread.run(Thread.java:744) 
Created at: 
io.netty.util.ResourceLeakDetector.open(ResourceLeakDetector.java:190) 
io.netty.buffer.AbstractByteBufAllocator.toLeakAwareBuffer(AbstractByteBufAllocator.java:42) 
io.netty.buffer.UnpooledByteBufAllocator.newDirectBuffer(UnpooledByteBufAllocator.java:55) 
io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:155) 
io.netty.buffer.AbstractByteBufAllocator.directBuffer(AbstractByteBufAllocator.java:146) 
io.netty.buffer.Unpooled.directBuffer(Unpooled.java:127) 
io.netty.buffer.Unpooled.copiedBuffer(Unpooled.java:417) 
ru.pb.battle.network.client.BattleClientConnection.channelRead0(BattleClientConnection.java:89) 
ru.pb.battle.network.client.BattleClientConnection.channelRead0(BattleClientConnection.java:42) 
io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) 
io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) 
io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) 
io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) 
io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:93) 
io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:485) 
io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:452) 
io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:346) 
io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) 
java.lang.Thread.run(Thread.java:744) 

====================== PBUDPServerPacket

public class PBUDPServerPacket { 
    private ByteBuf buff; 
    private InetSocketAddress addr; 

    public PBUDPServerPacket(int opcode, ByteBuf data, InetSocketAddress recipient, byte slot, byte[] ignore, int accountId) { 
     buff = Unpooled.buffer().order(ByteOrder.LITTLE_ENDIAN); 
     buff.writeByte(opcode); 
     buff.writeByte(slot); 
     buff.writeBytes(ignore); 
     buff.writeByte(accountId); 
     buff.writeBytes(data); 
     addr = recipient; 
    } 

    public DatagramPacket getPacket() { 
     return new DatagramPacket(buff, addr); 
    } 
} 

回答

3

你需要调用releaseByteBuf而不是clear在您的finally块中,否则参考计数的缓冲区没有正确解除分配。

+0

感谢您的回复。我尝试了很多选择,但没有任何帮助。也许我做错了什么?请告诉我正确的源代码。 – user3615911

+0

finally { bb.release(); } – user3615911

+0

finally {bb.release(); } 就这些? – user3615911