尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
生产大文件下载导致 OOM,顺藤摸瓜拿下
上周遇到了生产环境 OOM 的问题找了一番之后基本定位了是大文件下载导致的问题于是在网上搜罗了一番文章下面分享一篇优质的解决方案整个排查思路非常清晰小白可以直接对照着来排查。事故发生上周五下午运营人员反馈笔者所负责的后台系统从 14 点以后就卡卡的虽然页面能够正常加载但是一直处于数据加载中数据也提交不了怀疑笔者的系统有BUG当听到运营人员的反馈我的第一反应是这不可能啊这么简单的一个后台系统还能出事故处理流程摘除其中一台服务器用于保留现场其他服务器先重启保证系统可用。下载GC日志系统dump文件用于分析GC log分析系统启动参数JVM内存分配-Xmx4096m -Xms4096m -Xmn2560m观察日志可知系统每隔 40S 发生一次 Full GC耗时 200 毫秒回收以后系统老年代占用也不大才 15M但是新生代回收完还有 2 个 G。有点不可思议竟然不是老年代塞满了数据而是新生代塞满了数据。初步推测是新生代数据要晋升到老年代结果放不进去而引起的 Full GC。使用 MAT 对 Dump 文件进行分析通过总图可以看出来目前系统内存占用超过 2 个 G:点击 Histogram 进行进一步分析看出系统中占用最多的是byte[]点击List Objects进入income引用统计界面层层点开发现byte[]被 ResponseEntity 对象所引用且数量不小翻阅代码1在系统中找到唯一ResponseEntity有关的代码2这代码看似没什么问题啊这不是很正常的文件下载么我去看看用户下载了啥跑到目录文件查看一下下。img我的天用户下载的是一份2.4G的大文件代码中FileUtils.readFileToByteArray(file)的方式是把整个文件读取到内存再输出流里写入此时内存不够分配又塞不进老年代只能是 Full GC 了。3成功破案了用户下载了一份大文件文件先加载到内存才往外写抹泪。。。。解决方案使用FileSystemResourceGetMapping(/down) public ResponseEntity download(RequestParam(uri) String uri) throws IOException { File file new File(uri); if (!file.isFile()) { throw new ServiceException(文件不存在); } String filename FilenameUtils.getName(uri); HttpHeaders headers new HttpHeaders(); headers.add(Content-Disposition, attachment;filename URLEncoder.encode(filename, UTF-8)); HttpStatus status HttpStatus.OK; return new ResponseEntity(new FileSystemResource(file), headers, status); }使用缓存流边读边写GetMapping(/down) public void download(RequestParam(uri) String uri, HttpServletResponse response) throws IOException { File file new File(uri); if (!file.isFile()) { throw new ServiceException(文件不存在); } String filename FilenameUtils.getName(uri); response.setHeader(Content-Disposition, attachment;filename URLEncoder.encode(filename, UTF-8)); try (FileInputStream fileInputStream new FileInputStream(file); BufferedInputStream bufferedInputStream new BufferedInputStream(fileInputStream); BufferedOutputStream bufferedOutputStream new BufferedOutputStream(response.getOutputStream())) { FileCopyUtils.copy(bufferedInputStream, bufferedOutputStream); } finally { // 使用的是try-with-resources } }文件存储到 oss 或者是七牛云将文件存储到 oss 或者是七牛云绕过服务器下载
RELATED

相关推荐

深夜弹窗 0xc000007b 背后的真凶:一次 Visual C++ 运行库的完整修复记录

深夜弹窗 0xc000007b 背后的真凶:一次 Visual C++ 运行库的完整修复记录

深夜弹窗 0xc000007b 背后的真凶:一次 Visual C 运行库的完整修复记录 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 如果程序启动时弹出"无法…

📅 2026/10/6 1:34:27
健康160抢号神器91160-cli:5分钟跑通全自动挂号脚本,从此告别手动刷号

健康160抢号神器91160-cli:5分钟跑通全自动挂号脚本,从此告别手动刷号

健康160抢号神器91160-cli:5分钟跑通全自动挂号脚本,从此告别手动刷号 【免费下载链接】91160-cli 健康160全自动挂号脚本,捡漏神器 项目地址: https://gitcode.com/gh_mirrors/91/91160-cli 很多人在健康160上预约热门专家时&#xf…

📅 2026/10/20 8:17:50
C语言学习笔记(八):结构体进阶

C语言学习笔记(八):结构体进阶

目录 1. 结构体类型声明进阶 1.1 嵌套结构体类型1.2 结构体的自引用1.3 typedef简化结构体类型1.4 匿名结构体类型 2. 结构体数组3. 结构体内存对齐 3.1 对齐规则3.2 为什么存在内存对齐3.3 结构体设计的技巧3.4 修改默认对齐数 1. 结构体类型声明进阶 1.1 嵌套结构体类型 在…

📅 2026/11/1 2:59:56
MORE NEWS

更多资讯

📰

【芳芯科技】果蔬运输车保鲜系统

实物效果图:实现功能:1.采用STM32单片机作为控制核心。2.MQ316硫化氢传感器实时检测气体浓度。3.DHT11实时检测环境温度和湿度。4.震动传感器检测是否触发震动报警。5.数据采用OLED显示屏进行显示。6.采集数据也会通过蓝牙实时发送到手机新型显示。7.采集…

📰

力扣(python3自用)2026.4.22

又是好久都没有刷题,今天把二叉树的题顺一遍 236.二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x&#xf…

📰

浩鑫能源|800W 换电柜电源/充电器

换电柜电源800W 90V 15ACY-0256智能电源模块的领跑者在共享经济与物联网设备爆发的时代,充电柜、智能快递柜、通信交换机等设备已成为城市基础设施的重要组成部分。然而,这些设备的“心脏”——电源系统,却常常面临电压不稳、环境复杂、管理困…

📰

转:读书的重要性

个人理解: 走出小我,成就大我 跳出此时此地的限制,穿透一时一地的迷雾,从更大的格局和更长远的眼光来把握眼前的各种扰动,从而把不解和不安化成豁然开朗和淡定从容,最后养成战略上的定力为什么读书对领导者…

📰

Altium Designer(AD20)-生成网络表及更新PCB板

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

深度揭秘:Hermes Agent如何构建企业级多智能体通信架构

深度揭秘:Hermes Agent如何构建企业级多智能体通信架构 在当今分布式AI系统日益复杂的背景下,多智能体协作的效率直接决定了系统的整体性能。Hermes Agent作为一款面向企业级应用的开源多智能体框架,通过创新的消息传递机制和智能协调协议&a…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬