程序员的语言“艳遇史”(六)——网络工程师perl 📅 发布时间:2026/7/8 1:10:31 👁️ 浏览次数: 章凹匀热通过dump以及日志分析我们已经知道了问题代码所在就是使用easyexcel上传、解析文件开发同学没有做分页导致内存溢出。这点在easyexcel文档也有提到参见。内存溢出后触发频繁的full gc由于gc很难有效回收内存所以程序抛出了OutOfMemoryError原因是Java heap space。关于OOM的异常原因我们也需要知道有如下几种Java heap space内存无法分配新的对象。典型的场景是内存不足内存泄漏分配的对象过大。GC Overhead limit exceededgc回收异常多次发生了98%的时间用于gc但只回收2%的内存。典型的场景是内存不足内存泄漏。Metaspace元空间不足。典型的场景是元空间设置太小程序异常创建过多的Class。Direct buffer memory直接内存不足。典型的场景是直接内存设置太小直接内存泄漏。Unable to create new native thread无法创建新的线程。典型的场景是系统ulimit -u设置太小。Requested array size exceeds VM limi数组大小太大。典型的场景是new ClassA[Long.MAX_VALUE]CodeCachejit编译缓存溢出。典型的场景是jit缓存设置过小。注意我们上面提到问题的是内存溢出而不是内存泄漏两者有本质的区别。内存溢出通常是分配大对象应用内存不足通常分配多点空间就可以解决问题而且所占的内存用完还是可以被回收的。内存泄漏则是程序有问题内存是无法被回收的分配再多的空间也都会被慢慢消耗完。打个比方内存溢出只是人长得不好看不是坏人内存泄漏则长得不好看也是坏人。当然两者我们都需要对其进行优化。通过我们的观察也发现确实如此经过一段时间后文件解析数据处理完内存就被回收了也没有full gc了。但问题来了此时应用http请求还是继续报错的依然是connection reset by peer。这点就不好理解了应用恢复了为什么tomcat没有恢复tomcat线程此时在做什么从日志也看不到tomcat相关错误tomcat假死了。从监控上看挂掉之前tomcat的请求线程数和连接数没有什么波动。我们的两个核心问题是什么是connection reset by peertomcat线程此时处于什么状态连接报错我们搜索源码并没有抛出connection reset by peer的代码也就是可能是jvm层面的抛出或者系统层面的抛出。既然是跟connection相关那我们就用netstat命令看下当前进程的连接情况netstat -tlnp | grep 8100netstat -anp | grep 8100从输出可以发现有一个特殊的101我们用正常的进程看一般都是0。这个参数叫backlog表示连接等待队列的长度对应tomcat的acceptCount参数默认是100。当连接超过这个值时就会报connection reset by peer我们当前是101所以新来的请求就被拒绝了。tomcat线程模型对于第二个问题tomcat线程正在干什么。一般我们可以通过jstack pid导出线程堆栈分析不过当我们的服务运行一段时间例如好几天后执行jstackjmap都会报错似乎是某些信息被系统清除掉这点我还找到根本原因如果你知道答案请告知我一下。幸好有arthas我们可以通过thread命令查看线程和其堆栈信息。thread -n 10 #top 10 cputhread 1 #展示线程1的堆栈thread --all #展示所有线程thread --all | grep http #展示http线程我们可以看到tomcat的10个核心线程还是在的且处于waitting状态。处于waitting状态是因为它在等任务执行从堆栈可以看出是阻塞在TaskQueue.take方法org.apache.tomcat.util.threads.TaskQueue是tomcat中的LinkedBlockingQueue是生产者-消费者模型take方法阻塞表示当前队列是空的没有任务需要执行一旦有任务放入TaskQueuetake方法就会唤醒进入Runnable状态。这点就很奇怪了前面说连接队列都满了但tomcat任务队列确是空的执行线程都处于等待任务状态一边满载一边空闲。要搞清楚这个问题需要我们对tomcat线程模型有所了解。tomcat支持几种IO模型BIO、NIO、AIO(NIO2)、APR我们可以通过server.tomcat.protocol参数进行设置默认用的是NIONIO是一种同步非阻塞IO。NIO的核心目的是可以用少量线程处理大量连接在linux用select/poll/epoll实现。NIO在很多中间件都有应用kafka,redis,rocketmq,gateway等等可以说涉及到网络处理的都离不开NIO。AIO是真正的异步IO但Linux对其支持不够完善且NIO已经足够高效所以NIO用得最多。reactor模型如何更好的实现NIO是个问题就好像我们实现某个功能要用到设计模式一样reactor就是NIO一种实现模式。doug lee在scalable io in java总结了3种模型单reactor单线程整个过程由一个线程完成包括创建连接读写数据业务处理。redis 6.0以前的版本就是这种模式实现起来简单没有线程切换加锁的开销。缺点是单线程不能发挥多核cpu的优势如果有一个业务处理阻塞了那么整个服务都会阻塞。单reactor多线程接收连接(accept)和IO读写还是由一个线程完成但业务处理会提交给业务线程池业务处理不会阻塞整个服务。多reactor多线程接收连接由一个main reactor处理建立连接后将其注册到sub reactor上每个sub reactor都是单reactor多线程模式。tomcat的实现tomcat的NIO由3种线程实现分别是Acceptor线程、Poller线程、请求处理线程。对于请求处理线程池我们比较熟悉常用的两个参数server.tomcat.minSpareThreads 10server.tomcat.maxThreads 200对应到reactor模型可以看成它是一种多reactor多线程模型Acceptor线程负责建立连接然后将建立好的连接注册到Poller由Poller进行读写。Poller读写后创建请求将其交给请求处理线程池。Acceptor和Poller线程对应的run方法都是一个死循环源源不断的接收连接、读写连接。从reactor模型上看在多核cpu下多reactor多线程模型可以获得更高的效率但tomcat10以下默认只能有一个Acceptor和一个Poller线程。源码分析源码位置org.apache.tomcat.util.net.NioEndpoint#startInternal开启Acceptor线程和Poller线程源码位置org.apache.tomcat.util.net.Acceptor#runwhile循环建立连接源码位置org.apache.tomcat.util.net.NioEndpoint.Poller#runwhile循环读取数据源码位置org.apache.tomcat.util.net.AbstractEndpoint#processSocket将封装好的请求交给请求线程池处理关于tomcat线程池有一个点要注意它和jdk不一样的是它是先开启核心线程当任务超过核心线程数就继续开启至最大线程数如果还超过才进入等待队列。水落石出通过上面的分析让我们回到问题出现时的这张图可以看到Acceptor和Poller线程消失了这样我们现象就很好解释了Acceptor没有拿新的连接来处理了此时连接在系统层面积压tomcat请求处理线程空闲。我们重启后再执行一下thread命令正常的是从Acceptor源码上看它捕获了异常但对于OOM选择重新抛出Acceptor线程就中断了可见OOM对于tomcat来说是个致命异常一旦程序有此类报错需要优化否则可能导致整个服务异常。且Acceptor和Poller线程抛出这个位置在打印日志之前所以也看不到错误日志这点似乎不太好但最新的tomcat版本也是保持如此。如果要获得这个日志我们也可以通过Thread的全局异常来捕获Thread.setDefaultUncaughtExceptionHandler((t, e) - {if (t.getName().equals(http-nio-8100-Acceptor)) {log.error(tomcat Acceptor error, t);}});总结OOM异常对于tomcat服务来说是致命的发现即需要处理。对于内存泄漏来说留有时间给我们dump内存分析。但对于内存溢出来说由于其会回收可能在某个时间OOM顺便把tomcat打挂了然后就回收了此时我们去dump也未必有用所以-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath 参数是很有必要需要加上的。
Discuz!NT负载均衡方案 兆昂葱缘我们在生活中最先接触的是细节,比如看到各种动作后,才开始对它们进行分类,才会去思考他们的叫声是不同,走路也是不同的。这种从细节到整体的思维方式,恰恰可以指导我们在编程中合理地使用继承。 自下而上&… 2026/5/17 10:25:47
C#会重蹈覆辙吗?系列之:论C#性能不能承受之慢 肆淖炊收进入Ollama官方网站后,可以看到Ollama已经支持DeepSeek-R1的部署: 点击DeepSeek-R1的链接可以看到有关deepseek-r1的详细介绍: 目前deepseek-r1模型大小提供了7个选择:1.5b、7b、8b、14b、32b、70b、671b。 因为我笔记本的… 2026/7/5 22:57:39
利用WCF的PP共享剪贴板上的数据 由残阅莱1.理论习题 【中英】【吴恩达课后测验】Course 1 - 神经网络和深度学习 - 第二周测验 这是本周理论部分的习题和相应解析,博主已经做好了翻译和解析工作,因此便不再重复,但有一题涉及到代码中矩阵的两种乘法,我们把这道… 2026/7/5 14:45:07
微软报告揭露全球AI真相:84%从未用过,DeepSeek如何让中国撕开一道口子 如果我告诉你,全球大约每6个人里面,才有1个人真正用过AI问答工具,大约每 333 个人里,才有1个人愿意为AI每月付费 20 美元,大约每2500个人里,才有1个人在使用代码辅助工具(深度使用AI工具&#x… 2026/7/8 1:09:09
【安全与故障排查】04-Redis未授权访问漏洞修复与防御体系建立 Redis 未授权访问漏洞修复与防御体系建立 专栏: 安全 & 故障排查 难度: 进阶 标签: Redis安全 未授权访问 漏洞修复 安全防护前言 Redis 未授权访问是危害极大的漏洞,轻则数据泄露,重则通过写入 crontab 或 SSH 公… 2026/7/8 1:07:09
AI时代,服务的主角依然是人|笃实科技客户服务最佳实践 在刚刚结束的第十届中国客户服务节上,「共生」服务创新与服务品牌论坛成为行业关注的焦点。 论坛中,飞书增值体验中心负责人林默分享了《AI浪潮下的服务底蕴》,围绕AI时代客户服务的发展方向进行了深入思考。其中有一个观点,引发… 2026/7/8 1:03:08
Barlow字体终极指南:为什么这款开源字体能彻底改变你的设计工作流? Barlow字体终极指南:为什么这款开源字体能彻底改变你的设计工作流? 【免费下载链接】barlow Barlow: a straight-sided sans-serif superfamily 项目地址: https://gitcode.com/gh_mirrors/ba/barlow 你是否曾在深夜的设计项目中,为了… 2026/7/8 0:59:07
ChatGPT生成的图表靠谱吗?5个常见错误与检查方法 摘要本文整理ChatGPT生成数据图表时常见的5类问题,包括图表类型选错、坐标轴误导、数据单位混乱、异常值未处理和过度解读趋势,并给出相应的检查方法。关键词: ChatGPT、数据可视化、Excel、图表、数据分析前言把Excel或CSV上传给ChatGPT后&a… 2026/7/8 0:59:07
WSEN-ISDS 6DOF IMU与PIC18F87J50的运动跟踪方案 1. 项目背景与硬件选型解析在自动化控制、机器人导航和工业设备监测领域,精确的空间运动感知是实现智能化的基础需求。传统方案往往需要分别部署加速度计和陀螺仪模块,不仅增加了系统复杂度,还面临数据同步的挑战。WSEN-ISDS (2536030320001)… 2026/7/8 0:59:07
BetterNCM安装器:高效管理网易云插件的最佳选择 BetterNCM安装器:高效管理网易云插件的最佳选择 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 还在为网易云音乐插件的繁琐安装流程而烦恼吗?BetterNCM安装器是… 2026/7/8 0:02:48
运动控制系统安全设置对比:ECI3808的3种限位保护与急停逻辑实现 运动控制系统安全机制深度解析:限位保护与急停逻辑的设计哲学在精密制造与自动化领域,运动控制系统的安全设计绝非简单的功能堆砌,而是一套融合了机械工程、电气原理和软件算法的防御体系。当一台数控机床以每分钟数万转的速度运转࿰… 2026/7/8 0:06:48
AI大模型应用开发:小白也能抓住的红利风口,收藏这篇入门指南! 文章指出,虽然微软等科技巨头在裁员,但英伟达等公司却在积极扩招AI相关人才,尤其是具身智能、仿真等领域。AI行业正在经历结构性调整,传统岗位被淘汰,而大模型应用开发等新岗位需求旺盛。对于想转行或学习AI的普通人来… 2026/7/8 0:10:49
6个月转型AI工程师:实战路径与核心技能 1. 项目概述:6个月转型AI工程师的可行性路径在2023年大模型技术爆发的背景下,AI工程师岗位需求同比增长217%(LinkedIn数据)。不同于传统算法工程师需要3-5年培养周期,现代AI工程师更侧重工程化落地能力。我在硅谷科技公… 2026/7/7 11:26:57
TPAFE0808与PIC18F87K22的多通道信号采集方案 1. 项目背景与核心需求在工业自动化、医疗设备和科研仪器等领域,多通道信号采集与系统监测是基础且关键的技术需求。传统方案往往面临通道数量不足、信号调理复杂、系统集成度低等问题。TPAFE0808作为一款8通道模拟前端芯片,与PIC18F87K22微控制器的组合… 2026/7/7 11:26:57
STC3115与PIC18LF26K80构建高精度电池管理系统 1. STC3115与PIC18LF26K80在电池管理系统中的核心价值在现代电子设备中,电池管理系统(BMS)的重要性不亚于设备的核心处理器。STC3115作为一款高精度电池电量监测IC,与PIC18LF26K80微控制器的组合,构成了一个既能精确监控又能智能管理的完整解… 2026/7/7 11:26:58