java执行socket.write对java堆内的数组数据进行网络IO操作时,其实分两步进行:
1.把java堆的数据拷贝到C堆内存中(对Java来说就是堆外内存,只是这个内存不归java管理)
2.把C内存中的数据发送到内核内存中,进行网络IO操作
疑问: 为何jvm不直接把数据从java堆发送到内核内存中进行网络IO操作,而要先把数据拷贝到C堆内存中
答案是:进行网络IO操作时其实底层调用的是c的函数write,该函数对应的字节数组的地址不能够变化,如果使用的java堆内的地址的话,由于gc的影响,有可能从新生带移动到了老年代,导致地址变化,所以不能够使用这个java堆内存作为底层write函数的地址,而必须申请另外的c内存地址并把数据拷贝过去
netty的参数-Dio.netty.leakDetectionLevel=paranoid可以查看netty是否发生了内存泄漏,可以在排查问题的时候使用