Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一直报这个错,是哪里使用有问题吗,我项目里本身没有用到 netty,这个错误应该是jkcp 层报出来的 #19

Open
dingzhichao opened this issue Oct 12, 2018 · 16 comments
Labels

Comments

@dingzhichao
Copy link

[nioEventLoopGroup-2-1] WARN io.netty.util.ReferenceCountUtil - Failed to release a message: DatagramPacket(/0.0.0.0:6000 => /127.0.0.1:64272, PooledUnsafeDirectByteBuf(freed))
io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1

@beykery
Copy link
Owner

beykery commented Oct 19, 2018

请把代码贴出来。

@dingzhichao
Copy link
Author

public void handleReceive(ByteBuf byteBuf, KcpOnUdp kcpOnUdp) {
int sessionId = kcpOnUdp.getKcp().getConv();
int length = byteBuf.readableBytes();//得到可读字节数
byte[] bytes = new byte[length]; //分配一个具有length大小的数组
byteBuf.getBytes(0, bytes); //将缓冲区中的数据拷贝到这个数组中
byteBuf.release();
FSPSession session = null;
boolean isNewSession = false;
if (sessionMap.containsKey(sessionId)) {
session = sessionMap.get(sessionId);
} else {
session = new FSPSession(sessionId, kcpOnUdp);
sessionMap.put(sessionId, session);
isNewSession = true;
}
session.handleReceive(bytes, isNewSession);

}

@dingzhichao
Copy link
Author

public class UdpServer extends KcpServer {

Map<Integer, FSPSession> sessionMap = new HashMap<>();

private static Logger log = LoggerFactory.getLogger(UdpServer.class);

public UdpServer(int port, int workSize) {
    super(port, workSize);
}

@Override
public void handleReceive(ByteBuf byteBuf, KcpOnUdp kcpOnUdp) {
    int sessionId = kcpOnUdp.getKcp().getConv();
    int length = byteBuf.readableBytes();//得到可读字节数
    byte[] bytes = new byte[length];    //分配一个具有length大小的数组
    byteBuf.getBytes(0, bytes); //将缓冲区中的数据拷贝到这个数组中
    byteBuf.release();
    FSPSession session = null;
    boolean isNewSession = false;
    if (sessionMap.containsKey(sessionId)) {
        session = sessionMap.get(sessionId);
    } else {
        session = new FSPSession(sessionId, kcpOnUdp);
        sessionMap.put(sessionId, session);
        isNewSession = true;
    }
    session.handleReceive(bytes, isNewSession);

}

@Override
public void handleException(Throwable throwable, KcpOnUdp kcpOnUdp) {
    log.error(throwable.getMessage());
}

@dingzhichao
Copy link
Author

麻烦请问下,该开源项目有线上游戏项目在用

@beykery
Copy link
Owner

beykery commented Nov 9, 2018

很显然你需要把 byteBuf.release();这行注销掉

@dingzhichao
Copy link
Author

很显然你需要把 byteBuf.release();这行注销掉

这个 byteBuf.release() 是后面加上才去的, 没加之前都报哪个错,我去掉之后也会报。
WARN io.netty.util.ReferenceCountUtil - Failed to release a message: DatagramPacket(/0.0.0.0:6666 => /127.0.0.1:51373, PooledUnsafeDirectByteBuf(freed))

大佬,你看下这个,貌似说 dp 释放失败。

@beykery
Copy link
Owner

beykery commented Nov 15, 2018

int length = byteBuf.readableBytes();//得到可读字节数
byte[] bytes = new byte[length]; //分配一个具有length大小的数组
byteBuf.getBytes(0, bytes); //将缓冲区中的数据拷贝到这个数组中
byteBuf.release();
这段是啥?
你应该参考下我写的demo。

@beykery
Copy link
Owner

beykery commented Nov 15, 2018

ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
启动的时候加上这个试试?

@dingzhichao
Copy link
Author

int length = byteBuf.readableBytes();//得到可读字节数
byte[] bytes = new byte[length]; //分配一个具有length大小的数组
byteBuf.getBytes(0, bytes); //将缓冲区中的数据拷贝到这个数组中
byteBuf.release();
这段是啥?
你应该参考下我写的demo。

嗯~ 其实就是参考你的那个testServer demo 来写的,因为你的demo里面对收到消息处理很简单,直接是字符串,我接受消息是结构体,所以需要解析 netty 的ByteBuf,
int length = byteBuf.readableBytes();//得到可读字节数
byte[] bytes = new byte[length]; //分配一个具有length大小的数组
byteBuf.getBytes(0, bytes); //将缓冲区中的数据拷贝到这个数组中
这段的意思就是把ByteBuf 的所欲 读到 字节数组中来,以便给后续逻辑处理

@dingzhichao
Copy link
Author

ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
启动的时候加上这个试试?

这个其实加过,但是还是一样报错。

@dingzhichao
Copy link
Author

int length = byteBuf.readableBytes();//得到可读字节数
byte[] bytes = new byte[length]; //分配一个具有length大小的数组
byteBuf.getBytes(0, bytes); //将缓冲区中的数据拷贝到这个数组中
byteBuf.release();
这段是啥?
你应该参考下我写的demo。

嗯~ 其实就是参考你的那个testServer demo 来写的,因为你的demo里面对收到消息处理很简单,直接是字符串,我接受消息是结构体,所以需要解析 netty 的ByteBuf,
int length = byteBuf.readableBytes();//得到可读字节数
byte[] bytes = new byte[length]; //分配一个具有length大小的数组
byteBuf.getBytes(0, bytes); //将缓冲区中的数据拷贝到这个数组中
这段的意思就是把ByteBuf 的所欲 读到 字节数组中来,以便给后续逻辑处理

@dingzhichao
Copy link
Author

int length = byteBuf.readableBytes();//得到可读字节数
byte[] bytes = new byte[length]; //分配一个具有length大小的数组
byteBuf.getBytes(0, bytes); //将缓冲区中的数据拷贝到这个数组中
byteBuf.release();
这段是啥?
你应该参考下我写的demo。

其实这段的 主要目的 就是把 数据 读到 byte数组,然后后面逻辑 用这个byte数组 进行反序列化
public void OnReceive(byte[] bytes, boolean isNewSession) {
try {
kcpNeedUpdateFlag = true;
FSPDataC2S dataC2S = FSPDataC2S.parseFrom(bytes); //反序列化
onReceiveFSPData(dataC2S, isNewSession);//对接收到的数据进行 逻辑处理
} catch (Exception e) {
e.printStackTrace();
}
}

@beykery
Copy link
Owner

beykery commented Nov 15, 2018

其实也不影响什么,它自己会保证不用的buf被release;不过我真没找到到底哪里的问题。

@dingzhichao
Copy link
Author

嗯,通信过程中报错了,但是确实没有发生丢包,就是报错报到后面,内存溢出了,所以担心后面 通信的客户端数量上去了,服务器会crash掉

@beykery
Copy link
Owner

beykery commented Nov 19, 2018

ResourceLeakDetector没关闭的话,没问题的。

@beykery beykery added the bug label Apr 26, 2020
@365082218
Copy link

365082218 commented Jun 28, 2021

我也有这个问题,就是自己handlerReceive里,如果不对bytebuf.release那么时间久了内存就申请溢出了,如果释放就会出现引用计数这个,然后服务端好像就不正常了,都是累积了一段时间才会这样,我感觉是库本身对bytebuf的申请和释放有问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants