精华内容
下载资源
问答
  • 但是我们在业务逻辑中使用类似readBytes方法读取到ByteBuf则需要我们手动调用release()方法去释放,不然就会挤压,jvm的GC也不会对其进行回收,直到netty抛出堆外内存溢出异常。 io.netty.handler.codec....

    在使用netty实现服务端或者客户端读取数据时,我们一般会继承SimpleChannelInboundHandler重写channelRead0方法,这个netty会自动帮我们释放堆外内存。

    但是我们在业务逻辑中使用类似readBytes方法读取到ByteBuf则需要我们手动调用release()方法去释放,不然就会挤压,jvm的GC也不会对其进行回收,直到netty抛出堆外内存溢出异常。

    io.netty.handler.codec.DecoderException: io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 1879048192, max: 1884815360)
    展开全文
  • 导读Netty 是一个异步事件驱动的网络通信层框架,用于快速开发高可用高性能的服务端网络框架与客户端程序,它极大地简化了 TCP 和 UDP 套接字服务器等网络编程。Netty 底层基于 JDK 的 NIO,我们为什么不直接基于 ...

    导读

    Netty 是一个异步事件驱动的网络通信层框架,用于快速开发高可用高性能的服务端网络框架与客户端程序,它极大地简化了 TCP 和 UDP 套接字服务器等网络编程。

    Netty 底层基于 JDK 的 NIO,我们为什么不直接基于 JDK 的 NIO 或者其他NIO框架:

    1. 使用 JDK 自带的 NIO 需要了解太多的概念,编程复杂。
    2. Netty 底层 IO 模型随意切换,而这一切只需要做微小的改动。
    3. Netty自带的拆包解包,异常检测等机制让我们从 NIO 的繁重细节中脱离出来,只需关心业务逻辑即可。
    4. Netty解决了JDK 的很多包括空轮训在内的 Bug。
    5. Netty底层对线程,Selector 做了很多细小的优化,精心设计的 Reactor 线程做到非常高效的并发处理。
    6. 自带各种协议栈,让我们处理任何一种通用协议都几乎不用亲自动手。
    7. Netty社区活跃,遇到问题随时邮件列表或者 issue。
    8. Netty已经历各大RPC框架(Dubbo),消息中间件(RocketMQ),大数据通信(Hadoop)框架的广泛的线上验证,健壮性无比强大。(以上优点摘自美团技术博客)

    背景

    最近在做一个基于异步事件驱动的基础框架,服务端使用实现 Vert.x框架,该框架底层网络通信基于 Netty 实现。基于对反应式编程的兴趣与研究,打算把Spring WebFlux与Vert.x结合在一起使用。

    理想目标是创建一个纯异步的、反应式编程框架。

    在完成初步目标(完成了Spring WebFlux与Vert.x整合使用)之后,进行初步的demo测试。在这个时候一切都没有问题,都按照理想中的步骤运行。基于对底层框架的负责以及展示区别于传统编程性能的提升。于是决定用Jmeter对这个demo进行压力测试。在压测一段时间后出现了netty堆外内存溢出的问题。此篇用来记录遇到问题以及排查解决问题的过程。为以后遇到这个问题的同学做下记录,避免此坑。

    问题

    整合Spring WebFlux与Vert.x后,底层网络通信使用netty,压测一段时间后,出现netty堆外内存溢出,如下图:

    662e8878d174f93390f2329270bdd880.png

    意思就是告诉我们netty去申请堆外内存的时候,出现了内存不足的情况。

    排查过程

    看到错误这种日志的时候,习惯性往最下面翻查,是reactor工作线程抛出的,除此之外没有任何有用信息。按照平时的排查思路,再去看dump文件,也没有发现任何异常(此处排除略)。

    阶段一:

    这个时候发现不能按照平时排查策略来解决问题,重新分析日志,这里有这么一段:

    5a8c70932b69fe026dfeff872f2910ca.png

    io.netty.util.internal.PlatformDependent.incrementMemoryCounter(...)是用来统计分配netty堆外内存的,其中有个字段用来保存已分配内存private static final AtomicLong DIRECT_MEMORY_COUNTER;于是决定把DIRECT_MEMORY_COUNTER这个字段值打印出来,用PlatformDependent.usedDirectMemory();可以直接获取,如下图:

    e6cdbd7a94c41b934bcc6da457833799.png

    阶段二:

    定位堆外内存增长速度,压测了几分钟后:

    6a335cee819faa3132d242b8a7bb9da2.png

    b1b87fb7fafff6f4c4961c54900c4b73.png

    发现是在不断的缓慢增长。

    阶段三:

    IDE中断点排查。

    断点决定打在处理请求、返回的处理器上,如下图:

    e45da2c518dc9014f3b50766c3f8b8af.png

    当断点进入这里的时候,一路F7进入调用方法中,并不断的观察控制台,堆外内存的大小变化。

    跟踪到如下图的位置,执行过这个断点的时候就会出现堆外内存使用统计变化:

    911d61f1c2dfade5e554e41bda081667.png
    申请堆外内存的地方

    7daeaf90d8e31fad168861af0aaf0e74.png
    堆外内存统计出现变化图

    到这里基础就找到堆外内存溢出问题的原因了,再来就是如何解决问题。

    阶段四:

    解决问题。

    因在org.springframework.http.codec.json.AbstractJackson2Encoder.encode(...)方法中申请了堆外内存分配,只需要在接口调用完毕的时候,手动释放此内存即可。

    620a3155ed4c945fa1347746061d775e.png

    阶段五:

    线上验证。

    1 测试服务器上,启动程序,启动参数如下:

    f52d90a1b0038058e28bfd98ae4360fa.png

    2 使用jmeter对用户分页接口进行压测(数据库:mysql),启动500个线程,压测10分钟,结果如下:

    945b2b53e00e4a131ee54e1d510aa3fa.png

    3 发现堆外内存使用变化:

    93113c792afc03a1076e49ba2644b494.png

    4 Arthas Dashboard监控:

    1e996415857a196e3b80f12f5e6b5b9d.png

    到此问题解决。

    展开全文
  • 导读Netty 是一个异步事件驱动的网络通信层框架,用于快速开发高可用高性能的服务端网络框架与客户端程序,它极大地简化了 TCP 和 UDP 套接字服务器等网络编程。Netty 底层基于 JDK 的 NIO,我们为什么不直接基于 ...

    导读

    Netty 是一个异步事件驱动的网络通信层框架,用于快速开发高可用高性能的服务端网络框架与客户端程序,它极大地简化了 TCP 和 UDP 套接字服务器等网络编程。

    Netty 底层基于 JDK 的 NIO,我们为什么不直接基于 JDK 的 NIO 或者其他NIO框架:

    1. 使用 JDK 自带的 NIO 需要了解太多的概念,编程复杂。
    2. Netty 底层 IO 模型随意切换,而这一切只需要做微小的改动。
    3. Netty自带的拆包解包,异常检测等机制让我们从 NIO 的繁重细节中脱离出来,只需关心业务逻辑即可。
    4. Netty解决了JDK 的很多包括空轮训在内的 Bug。
    5. Netty底层对线程,Selector 做了很多细小的优化,精心设计的 Reactor 线程做到非常高效的并发处理。
    6. 自带各种协议栈,让我们处理任何一种通用协议都几乎不用亲自动手。
    7. Netty社区活跃,遇到问题随时邮件列表或者 issue。
    8. Netty已经历各大RPC框架(Dubbo),消息中间件(RocketMQ),大数据通信(Hadoop)框架的广泛的线上验证,健壮性无比强大。(以上优点摘自美团技术博客)

    背景

    最近在做一个基于异步事件驱动的基础框架,服务端使用实现 Vert.x框架,该框架底层网络通信基于 Netty 实现。基于对反应式编程的兴趣与研究,打算把Spring WebFlux与Vert.x结合在一起使用。

    理想目标是创建一个纯异步的、反应式编程框架。

    在完成初步目标(完成了Spring WebFlux与Vert.x整合使用)之后,进行初步的demo测试。在这个时候一切都没有问题,都按照理想中的步骤运行。基于对底层框架的负责以及展示区别于传统编程性能的提升。于是决定用Jmeter对这个demo进行压力测试。在压测一段时间后出现了netty堆外内存溢出的问题。此篇用来记录遇到问题以及排查解决问题的过程。为以后遇到这个问题的同学做下记录,避免此坑。

    问题

    整合Spring WebFlux与Vert.x后,底层网络通信使用netty,压测一段时间后,出现netty堆外内存溢出,如下图:

    e55a30ab4d46bd32c086b90b271d709b.png

    意思就是告诉我们netty去申请堆外内存的时候,出现了内存不足的情况。

    排查过程

    看到错误这种日志的时候,习惯性往最下面翻查,是reactor工作线程抛出的,除此之外没有任何有用信息。按照平时的排查思路,再去看dump文件,也没有发现任何异常(此处排除略)。

    阶段一:

    这个时候发现不能按照平时排查策略来解决问题,重新分析日志,这里有这么一段:

    6a25c0fecdcd9680516dab28f9df18ac.png

    io.netty.util.internal.PlatformDependent.incrementMemoryCounter(...)是用来统计分配netty堆外内存的,其中有个字段用来保存已分配内存private static final AtomicLong DIRECT_MEMORY_COUNTER;于是决定把DIRECT_MEMORY_COUNTER这个字段值打印出来,用PlatformDependent.usedDirectMemory();可以直接获取,如下图:

    69c84769c78ea4552a959a31c6ddb07b.png

    阶段二:

    定位堆外内存增长速度,压测了几分钟后:

    45aa99975479bf0b25db582000a9347b.png

    4dcc20a4384acaf4c78d4fc258633946.png

    发现是在不断的缓慢增长。

    阶段三:

    IDE中断点排查。

    断点决定打在处理请求、返回的处理器上,如下图:

    87907e5703f6ef1b6d643cc6b9fbb9cd.png

    当断点进入这里的时候,一路F7进入调用方法中,并不断的观察控制台,堆外内存的大小变化。

    跟踪到如下图的位置,执行过这个断点的时候就会出现堆外内存使用统计变化:

    1ecad6456a9cf1c24fe786e73da0a6ed.png
    申请堆外内存的地方

    a6e28b5d67096cfc845408496d8cdc62.png
    堆外内存统计出现变化图

    到这里基础就找到堆外内存溢出问题的原因了,再来就是如何解决问题。

    阶段四:

    解决问题。

    因在org.springframework.http.codec.json.AbstractJackson2Encoder.encode(...)方法中申请了堆外内存分配,只需要在接口调用完毕的时候,手动释放此内存即可。

    be7789894bf24a00a990cf8044b880f6.png

    阶段五:

    线上验证。

    1 测试服务器上,启动程序,启动参数如下:

    7c686e7cd95395f0eb99220085906565.png

    2 使用jmeter对用户分页接口进行压测(数据库:mysql),启动500个线程,压测10分钟,结果如下:

    abe202feed3f2809b8fb0ed7d9d774f8.png

    3 发现堆外内存使用变化:

    f0338090bbe79f91f771a6adb9c52f7e.png

    4 Arthas Dashboard监控:

    4802121319f74d7be672b0507a566975.png

    到此问题解决。

    展开全文
  • Lettuce & Jedis redisTemplate (StringRedisTemplate类) Lettuce & Jedis 操作redis的底层客户端,Spring再次封装 redisTemplate ...Lettuce 的bug导致netty堆外内存溢出 设置JVM:-X

    Lettuce & Jedis

    redisTemplate (StringRedisTemplate类)

    Lettuce & Jedis 操作redis的底层客户端,Spring再次封装 redisTemplate
    在这里插入图片描述
    无论我们使用哪个服务,最后都可以获得连接工厂

    在这里插入图片描述

    堆外内存溢出

    原因:

    • springboot2.0 以后默认使用 Lettuce 作为操作redis的客户端
      它使用netty进行网络通信

    • Lettuce 的bug导致netty堆外内存溢出

    • 设置JVM:-Xmx300m

    • netty如果没有指定堆外内存,默认使用 -Xmx300m

    解决方案

    • 不能使用 -Dio.netty.maxDirectMemory只去调大堆外内存
    • 方式一:升级 Lettuce 客户端
    • 方拾二:切换使用 jedis
    <!--   引入 redis-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        
        <!-- 排除 lettuce -->
        <exclusions>
            <exclusion>
                <groupId>io.lettuce</groupId>
                <artifactId>lettuce-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
    <!--  引入 jedis-->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>
    
    展开全文
  •  1, 在第一个版本当中,为了性能考虑,netty默认使用了内存池以及堆外内存,在测试环境上表现良好,然而在线上的使用过程中发现,运行一周之后netty+https会导致内存溢出. 测试与生产的差异在于生产环境因为用户的复杂性...
  • 内存溢出错误, netty 版本为 4.1.32.Final. 和 4.1.25.Final 都有问题. 改为4.0.24.Final 后没有这个问题. <p>2019-04-24 21:41:26,348 [SOFA-SEV-REST-BIZ-8341-4-T2] WARN ...
  • Netty使用案例 -堆外内存泄漏跟踪

    千次阅读 2019-01-15 17:11:40
    内存池ByteBuf泄漏没有引起堆内存溢出 服务端代码入下 public class RouterServerHandler extends ChannelInboundHandlerAdapter { static ExecutorService executorService = Executors.newSingleThreadExecutor()...
  • * 2、lettuce 的bug导致netty堆外内存溢出,-Xmx300m netty 如果没有指定堆内存移除,默认使用 -Xmx300m * 可以通过-Dio.netty.maxDirectMemory 进行设置 * 解决方案 不能使用 -Dio.netty.maxDirectMemo
  • springboot2.0 整合redis 默认使用的是 lettuce 操作的reids ,lettuce底层使用的netty进行网络通信,lettuce 的bug 导致netty堆外内存溢出,netty如果没有指定堆外内存,那么netty默认分配的堆外内存就会使用jvm 的...
  • 报错页面: 报错场景: 在使用jmeter进行压测 从redis 获取 商品分类结果,使用的是 spring boot 整合的 ...lettuce 的bug 导致netty堆外内存溢出, netty如果没有指定堆外内存,那么netty默认分配的堆外内存就会使
  • OutOfDirectMemoryError

    2021-01-21 01:00:24
    2.lettuce的bug导致netty堆外内存溢出 -Xmx300m; netty如果没有指定堆外内存,默认使用-Xmx300m 可以通过-Dio.netty.maxDirectMemory进行设置 解决方案: 不能使用 -Dio.netty.maxDirectMemory 只去调大堆外内存(时间...
  • springBoot整合redis

    2020-10-09 20:30:36
    2).lettuce的bug导致netty堆外内存溢出,netty如果没有指定堆外内存,默认使用-Xmx 3).可以通过-Dio.netty.maxDirectMemory进行设置,不能使用-Dio.netty.maxDirectMemory只去调大堆外内存 3. 解决方案: * 1.升级...
  • 151、缓存-缓存使用-本地缓存与分布式缓存 -157、缓存-缓存使用-本地锁在分布式下的问题 主要就是把数据缓存到redis中 ... //luttuce的bug导致netty堆外内存溢出 -Xmx300m;netty如没有指定,默认是-Xmx300m ...
  • io在使用netty时出现的堆外内存溢出异常,这种情况一般在大并发情况下较多出现 问题原因 出现其的原因:springboot整合redis在2.0以后默认使用lettuce来操作redis客户端, 而他使用netty进行网络通讯的 我在开发中并...
  • 1、引入maven <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-...-- Lettuce的bug导致netty堆外内存溢出 切换使用jedis--> <exclusio
  • Netty报Direct buffer memory错误

    千次阅读 2016-12-02 10:54:01
    最近在基于Netty实现NIO方面做应用底层通讯架构(服务发现,分布式,高可用,软负载)。...原因:Netty启用了堆外内存DirectByteBuffer实现了零拷贝,堆外内存对young gc免疫,只有在full gc的时候才被收
  • 日志记录中报堆外内存溢出。 3. 问题定位及修改 Netty提供了ByteBuf泄露的检测机制。 JVM启动参数中添加: -Dio.netty.leakDetectionLevel=advanced, log4j2.xml配置io.netty日志记录即可。 禁用(DISABLED...
  • 05-Netty的零拷贝技术

    2021-04-11 01:30:30
    所谓堆内存就是分配给JVM堆区的内存,而直接内存是java通过调用navite方法可以直接分配JVM之外的内存区域,所以我们也把这块内存叫做堆外内存。而我们可以在堆区通过一个DirectByteBuffer去引用这块内存。因为这块...
  • 1. 假设仅在接收客户端报文的时候会申请堆外内存,每个报文为1KB,程序最大的堆外内存为512MB,那么最大支持524288个客户端同时发包,超出可能会导致OOM。 2. 假设程序最大的Direct Memory(可由-XX:...
  • 关于资源, Java线程的线程栈所占用的内存是在Java堆外的,所以是不受java程序控制的,只受系统资源限制,默认一个线程的线程栈大小是1M(当然这个可以通过设置-Xss属性设置,但是要注意栈溢出问题),但是,如果每个...
  • 我一直都有一个疑问,丰巢业务服务的生产环境jvm参数设置是禁止system.gc的,也就是开启设置:-XX:+DisableExplicitGC,但是生产环境却从来没有出现过堆外内存溢出的情况。说明一下,丰巢使用了阿里开源的dubbo,而...
  • Jstorm

    2017-04-09 16:09:25
    RPC OOM(OOM - Out of Memory,内存溢出 ——俗称雪崩问题)一直没有解决原生Storm RPC:Zeromq 使用堆外内存,导致OS 内存不够,Netty 导致OOM; JStorm底层RPC 采用netty + disruptor,保证发送
  • 第02节、内存溢出与内存泄露的区别 第03节、引用计数法 第04节、复制算法 第05节、标记清除与标记压缩算法 第06节、分代算法 第07节、垃圾收集器与jmeter压力测试工具用法 第08节、tomcat参数调优测试-串行回收 第09...
  • 记一次大促期间JVM堆外内存泄漏故障排查记录 性能调优、线上问题排查 类加载机制详解 垃圾回收机制 垃圾回收器、垃圾回收算法 并发与多线程 线程状态转换与通信机制 线程同步与互斥 线程池知识点 常见的JUC工具...

空空如也

空空如也

1 2
收藏数 25
精华内容 10
关键字:

netty堆外内存溢出