热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【经验分享】OOM故障分析记录:byte[]占用了大量内存

现象:工作时遇到某个服务老是频繁重启,日志报错为OOM分析:出现OOM是因为整个堆内存不够用了,此时JVM首先尝试扩展更多的空间,其次GC尝试回收内存,前两种方法无果的情况下只能报

现象:

工作时遇到某个服务老是频繁重启,日志报错为OOM


分析:

出现OOM是因为整个堆内存不够用了,此时JVM首先尝试扩展更多的空间,其次GC尝试回收内存,前两种方法无果的情况下只能报OOM并退出

可能的情况:内存不够、内存泄漏


尝试解决问题的步骤:



  1. 加上JVM参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath= ,设置当出现OOM时,dump整个堆的信息

  2. 等OOM后,将文件拷贝到电脑上

  3. 用JDK自带的 visualVM,打开dump文件

    设置了最大堆大小 512M,从下图看出,确实占满了导致OOM

    20191122170147350.png

  4. 转到类实例占用大小视图,找到占用最大的类

    image.png

    可以看到,总共512M堆大小,byte[]对象占用了其中的90%,这显然是异常占用

    接下来转到实例视图,查看具体的实例

    image.png

    最大的byte[]对象占用了 约 10M

    拷贝byte[]对象中存储的内容,并在代码中构建byte[]对象存入String打印出可视化内容

    image.png

    打印出的部分String内容如下,可以看到存储的是 http header的内容,并且byte[]中99%的内容为0,说明大量空间并未被使用到

HTTP/1.1 200
Access-Control-Allow-Origin: *
Access-Contr

选其中的一个,选择显示最近的垃圾回收根节点

image.png

看到持有这个byte[]对象的是一个 HeapByteBuffer对象,HeapByteBuffer是java NIO中的对象。


程序中没有使用NIO,推测NIO应该在Tomcat中被使用,并且Tomcat的默认配置不可能为 10M这么不合理的值,那感觉可能是有不合理的自定义配置存在。

于是先去项目中找到如下相关配置:

image.png

发现,Tomcat中最大请求头大小被设置为 10M,和刚才byte[]对象占用的大小相似(多出的应为对象头以及其他多申请的空间,具体要参考源码),其次也和前面发现的byte[]对象中存储的是请求头信息的事实相符合,这应该就是问题所在,把这个配置调小点或者干脆使用默认配置即可。


问题总结:


咨询了相关同事,为了传输较大的文件,调大了 tomcat max-http-post-size,顺手改了 max-http-header-size,容器初始化处理请求的线程池时,每个线程都会申请 此处为 10M大小的byte[]对象,并且请求处理线程的生命周期一般和服务的生命周期一致,也就是说,线程持有的 byte[]对象在整个服务周期中是一直存活的。一般线程池的规模少说也在几十个,也意味着服务正常工作时,几百兆的堆内存(也可能是堆外内存,具体看Tomcat配置使用哪个)会被请求处理线程一直占用,当分配的内存较少时,很快OOM

转载:一次OOM故障分析记录:HeapByteBuffer byte[] 占用了大量内存



推荐阅读
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
author-avatar
vegg巛iegbaby
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有