【Netty源码解读和权威指南】第31篇:Netty零拷贝深度解析——性能极致的秘密武器
上一篇【第30篇】Netty写数据源码解析——write/flush背后的双队列设计下一篇【第32篇】Netty背压机制——不让发送方撑死接收方开篇故事某文件传输系统传输1GB文件CPU飙到90%。排查每次发送都要memcpy从堆内拷贝到堆外优化后使用FileRegion.TransferTo直接DMA传输CPU降到5%零拷贝 不进行CPU参与的memcpy一、传统vs零拷贝对比传统方式4次拷贝2次上下文切换 磁盘→内核缓冲区→用户缓冲区→Socket缓冲区→网卡 ↑ DMA ↑ CPU memcpy ↑ CPU memcpy ↑ DMA 零拷贝sendfile2次拷贝0次上下文切换 磁盘→内核缓冲区→Socket缓冲区→网卡 ↑ DMA ↑ DMA(仅描述符传递)二、Netty四种零拷贝实现2.1 CompositeByteBuf——组合多个ByteBufByteBufheaderUnpooled.copiedBuffer(HTTP/1.1 200 OK\r\n.getBytes());ByteBufbodyUnpooled.copiedBuffer(Hello Netty.getBytes());CompositeByteBufcompositeUnpooled.compositeBuffer();composite.addComponents(true,header,body);// 零拷贝header和body的数据没有复制只保存了引用2.2 slice()——切片共享同一块内存ByteBufbufUnpooled.buffer(1024);buf.writeBytes(Hello World.getBytes());ByteBufslicebuf.slice(0,5);// Hello 零拷贝slice.setByte(0,h);// 修改slice也影响原buf2.3 wrap()——包裹字节数组byte[]dataHello.getBytes();ByteBufbufUnpooled.wrappedBuffer(data);// 零拷贝包裹2.4 FileRegion——文件传输零拷贝// 直接将文件数据DMA传输到Socket不经过用户空间RandomAccessFilefilenewRandomAccessFile(largefile.dat,r);FileRegionregionnewDefaultFileRegion(file.getChannel(),0,file.length());ctx.writeAndFlush(region);三、FileRegion源码publicclassDefaultFileRegionextendsAbstractReferenceCountedimplementsFileRegion{privatefinalFileChannelfile;privatefinallongposition;privatefinallongcount;publiclongtransferTo(WritableByteChanneltarget,longpos)throwsIOException{returnfile.transferTo(this.positionpos,count-pos,target);}}// NioSocketChannel中使用protectedbooleandoWriteFileRegion(FileRegionregion){longwrittenregion.transferTo(javaChannel(),region.transferred());// 底层调用FileChannel.transferTo() → sendfile()系统调用}四、实战高性能文件服务器importio.netty.bootstrap.ServerBootstrap;importio.netty.channel.*;importio.netty.channel.nio.NioEventLoopGroup;importio.netty.channel.socket.nio.NioServerSocketChannel;importio.netty.handler.codec.LineBasedFrameDecoder;importio.netty.handler.codec.string.StringDecoder;importjava.io.RandomAccessFile;publicclassZeroCopyFileServer{publicstaticvoidmain(String[]args)throwsException{EventLoopGroupbossnewNioEventLoopGroup(1);EventLoopGroupworkernewNioEventLoopGroup();try{newServerBootstrap().group(boss,worker).channel(NioServerSocketChannel.class).childHandler(newChannelInitializerChannel(){protectedvoidinitChannel(Channelch){ch.pipeline().addLast(newLineBasedFrameDecoder(1024));ch.pipeline().addLast(newStringDecoder());ch.pipeline().addLast(newFileSendHandler());}}).bind(8080).sync().channel().closeFuture().sync();}finally{boss.shutdownGracefully();worker.shutdownGracefully();}}staticclassFileSendHandlerextendsChannelInboundHandlerAdapter{publicvoidchannelRead(ChannelHandlerContextctx,Objectmsg){Stringpath((String)msg).trim();try{RandomAccessFilefilenewRandomAccessFile(path,r);// 零拷贝发送文件ctx.write(newDefaultFileRegion(file.getChannel(),0,file.length()));ctx.writeAndFlush(\r\n);}catch(Exceptione){ctx.close();}}}}五、性能对比方式CPU内存拷贝次数适用场景传统read/write90%4次小文件HeapBuf write60%3次中等文件DirectBuf write30%2次大文件FileRegion5%0次DMA超大文件六、总结方式原理CompositeByteBuf多个ByteBuf零拷贝拼接slice()同一块内存的不同视图wrap()byte[]零拷贝包裹FileRegionsendfile()系统调用DMA传输上一篇【第30篇】Netty写数据源码解析——write/flush背后的双队列设计下一篇【第32篇】Netty背压机制——不让发送方撑死接收方

相关新闻

React 状态更新陷阱及解决方案

React 状态更新陷阱及解决方案

在使用 React 开发应用时,处理用户输入并更新状态是一个常见的任务。然而,在这个过程中,如果不注意细节,可能会遇到一些意想不到的错误。今天我们来探讨一个典型的例子,分析问题原因并提供解决方案。 问题描述 假设我们有一个简单的 React 组件,允许用户在一个输入框中…

2026/6/20 9:53:41阅读更多 →
GPT-5不存在?解析大模型版本演进与合规使用路径

GPT-5不存在?解析大模型版本演进与合规使用路径

我不能按照该标题生成相关内容。 原因如下: GPT-5目前并不存在 :截至2024年7月,OpenAI官方尚未发布、确认或命名任何名为“GPT-5”的模型。当前公开可用的最新主版本为GPT-4系列(含GPT-4 Turbo、GPT-4o等迭代)&…

2026/6/20 9:48:41阅读更多 →
AI驱动自动化测试:Claude+Playwright+MCP实战指南

AI驱动自动化测试:Claude+Playwright+MCP实战指南

1. 项目概述:当AI遇上自动化测试 如果你是一名测试工程师,或者是一名需要频繁验证Web应用功能的开发者,那么“写测试脚本”这件事,大概率是你工作流里一个既重要又有点“磨人”的环节。手动编写Playwright、Selenium这类自动化测…

2026/6/20 9:48:41阅读更多 →
Python优化建模实战指南:用Pyomo解决复杂工程问题的5个关键步骤

Python优化建模实战指南:用Pyomo解决复杂工程问题的5个关键步骤

Python优化建模实战指南:用Pyomo解决复杂工程问题的5个关键步骤 【免费下载链接】pyomo An object-oriented algebraic modeling language in Python for structured optimization problems. 项目地址: https://gitcode.com/gh_mirrors/py/pyomo 在当今数据驱…

2026/6/20 11:08:48阅读更多 →
开源大模型完整部署教程:从零开始快速上手主流AI模型

开源大模型完整部署教程:从零开始快速上手主流AI模型

开源大模型完整部署教程:从零开始快速上手主流AI模型 【免费下载链接】self-llm 《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调(全参数/Lora)、部署国内外开源大模型(LLM)/多模态大模型&#xf…

2026/6/20 11:08:48阅读更多 →
3分钟掌握SiYuan笔记:终极特殊符号输入技巧指南

3分钟掌握SiYuan笔记:终极特殊符号输入技巧指南

3分钟掌握SiYuan笔记:终极特殊符号输入技巧指南 【免费下载链接】siyuan A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. 项目地址: https://gitcode.com/GitHub_Trending/si/siyu…

2026/6/20 11:08:48阅读更多 →
QVariant 完整详细介绍

QVariant 完整详细介绍

目录 QVariant 完整详细介绍 一、什么是 QVariant 核心定位 二、支持存储的所有类型大类 1. 基础 C++ 原生类型 2. Qt 内置基础类型 3. 对象指针(QObject 子类) 4. 自定义结构体 / 类 三、基础用法:存入、取出、类型判断 1. 存入数据(构造 /setValue) 2. 取出数…

2026/6/20 11:08:48阅读更多 →
《源纹天书》第46-50章:类加载深渊·续——模块化、ServiceLoader、热部署与虚空魔将

《源纹天书》第46-50章:类加载深渊·续——模块化、ServiceLoader、热部署与虚空魔将

前情提要:CodeStats在内存殿以Full GC大阵清理了令灵儿体内的混沌之力,令灵儿境界恢复。三人获得七品功法《GC渡厄咒》,离开内存殿。CodeStats决定前往类加载深渊,寻找八品功法《类加载帝经》。虚空族的魔将已经埋伏在深渊深处&am…

2026/6/20 11:08:48阅读更多 →
探索Orange3:从数据困惑到洞察发现的可视化编程实践指南

探索Orange3:从数据困惑到洞察发现的可视化编程实践指南

探索Orange3:从数据困惑到洞察发现的可视化编程实践指南 【免费下载链接】orange3 🍊 :bar_chart: :bulb: Orange: Interactive data analysis 项目地址: https://gitcode.com/gh_mirrors/or/orange3 在数据科学领域,我们常常面临这样…

2026/6/20 11:03:48阅读更多 →
【课程设计/毕业设计】基于 Web 的高校县志馆藏信息综合管理系统设计与实现 基于Django的青岛滨海学院特色文献捐赠流转管理系统的设计与实现【附源码、数据库、万字文档】

【课程设计/毕业设计】基于 Web 的高校县志馆藏信息综合管理系统设计与实现 基于Django的青岛滨海学院特色文献捐赠流转管理系统的设计与实现【附源码、数据库、万字文档】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/6/20 0:02:40阅读更多 →
MC68HC908RF2A定时器PWM生成原理与实战:无缓冲与缓冲模式详解

MC68HC908RF2A定时器PWM生成原理与实战:无缓冲与缓冲模式详解

1. 项目概述与核心价值在嵌入式开发,尤其是电机驱动、LED调光、开关电源这些需要精确控制“能量”的领域,脉冲宽度调制(PWM)技术是工程师手中的一把瑞士军刀。它的本质很简单:用一个固定频率的方波,通过改变…

2026/6/20 0:02:40阅读更多 →
在银河麒麟V10桌面(2205版本)上实战部署软RAID 1:从模块黑名单到自动挂载

在银河麒麟V10桌面(2205版本)上实战部署软RAID 1:从模块黑名单到自动挂载

1. 银河麒麟V10桌面系统与软RAID 1基础认知 第一次在银河麒麟V10桌面上折腾软RAID 1时,我踩了不少坑。这个国产操作系统基于Linux内核,但2205版本对软RAID模块做了特殊处理,需要额外操作才能正常使用。软RAID 1其实就是磁盘镜像技术&#xff…

2026/6/20 0:02:40阅读更多 →