JVM-虚拟机的故障处理与调优案例分析
案例1:大内存硬件上的程序部署策略
一个15万PV/日左右的在线文档类型网站最近更换了硬件系统,服务器的硬件为四路志强处理器、16GB物理内存,操作系统为64位CentOS 5.4,Resin作为Web服务器。整个服务器暂时没有部署别的应用,所有硬件资源都可以提供给这访问量并不算太大的文档网站使用。软件版本选用的是64位的JDK 5,管理员启用了一个虚拟机实例,使用-Xmx和-Xms参数将Java堆大小固定在12GB。
监控服务器运行状况后发现网站失去响应是由垃圾收集停顿所导致的,在该系统软硬件条件下,HotSpot虚拟机是以服务端模式运行,默认使用的是吞吐量优先收集器,回收12GB的Java堆,一次FullGC的停顿时间就高达14秒。由于程序设计的原因,访问文档时会把文档从磁盘提取到内存中,导致内存中出现很多由文档序列化产生的大对象,这些大对象大多在分配时就直接进入了老年代,没有在Minor GC中被清理掉。这种情况下即使有12GB的堆,内存也很快会被消耗殆尽。
主要问题:过大的堆内存进行回收时带来的长时间的停顿
单体应用在较大内存的硬件上主要的部署方式有两种:
1)通过一个单独的Java虚拟机实例来管理大量的Java堆内存。
使用单个Java虚拟机实例来管理大内存,还需要考虑下面可能面临的问题:
Ⅰ回收大块堆内存而导致的长时间停顿,自从G1收集器的出现,增量回收得到比较好的应用
Ⅱ大内存必须有64位Java虚拟机的支持,但由于压缩指针、处理器缓存行容量(Cache Line)等因
素,64位虚拟机的性能测试结果普遍略低于相同版本的32位虚拟机。
Ⅲ必须保证应用程序足够稳定,因为这种大型单体应用要是发生了堆内存溢出,几乎无法产生堆转
储快照(要产生十几GB乃至更大的快照文件),哪怕成功生成了快照也难以进行分析;如果确实出了
问题要进行诊断,可能就必须应用JMC这种能够在生产环境中进行的运维工具
2)同时使用若干个Java虚拟机,建立逻辑集群来利用硬件资源。
做法是在一台物理机器上启动多个应用服务器进程,为每个服务器进程分配不同端口,然后在前端搭建一个负载均衡器,以反向代理的方式来分配访问请求。
缺点:
Ⅰ节点竞争全局的资源,最典型的就是磁盘竞争,各个节点如果同时访问某个磁盘文件的话(尤其是并发写操作容易出现问题),很容易导致I/O异常。
Ⅱ很难最高效率地利用某些资源池,譬如连接池,一般都是在各个节点建立自己独立的连接池,这样有可能导致一些节点的连接池已经满了,而另外一些节点仍有较多空余。尽管可以使用集中式的JNDI来解决,但这个方案有一定复杂性并且可能带来额外的性能代价。
解决方案:
调整为建立5个32位JDK的逻辑集群,每个进程按2GB内存计算(其中堆固定为1.5GB),占用了10GB内存。另外建立一个Apache服务作为前端均衡代理作为访问门户。考虑到用户对响应速度比较关心,并且文档服务的主要压力集中在磁盘和内存访问,处理器资源敏感度较低,因此改为CMS收集器进行垃圾回收。
案例2:集群间同步导致的内存溢出
一个基于B/S的MIS系统,硬件为两台双路处理器、8GB内存的HP小型机,应用中间件是WebLogic9.2,每台机器启动了3个WebLogic实例,构成一个6个节点的亲合式集群。由于是亲合式集群,节点之间没有进行Session同步,但是有一些需求要实现部分数据在各个节点间共享。最开始这些数据是存放在数据库中的,但由于读写频繁、竞争很激烈,性能影响较大,后面使用JBossCache构建了一个全局缓存。全局缓存启用后,服务正常使用了一段较长的时间。但在最近不定期出现多次的内存溢出问题。
最近一次溢出之后,堆转储快照里面存在着大量的org.jgroups.protocols.pbcast.NAKACK对象
JBossCache是基于自家的JGroups进行集群间的数据通信,JGroups使用协议栈的方式来实现收发数据包的各种所需特性自由组合,数据包接收和发送时要经过每层协议栈的up()和down()方法,其中的NAKACK栈用于保障各个包的有效顺序以及重发。
由于信息有传输失败需要重发的可能性,在确认所有注册在GMS(Group Membership Service)的节点都收到正确的信息前,发送的信息必须在内存中保留。当网络情况不能满足传输要求时,重发数据在内存中不断堆积,很快就产生了内存溢出。
案例3:堆外内存导致的溢出错误
基于B/S的电子考试系统,为了实现客户端能实时地从服务器端接收考试数据,系统使用了逆向AJAX技术(也称为Comet或者Server Side Push),选用CometD 1.1.1作为服务端推送框架,服务器是Jetty 7.1.4,硬件为一台很普通PC机,Core i5 CPU,4GB内存,运行32位Windows操作系统。
问题:服务端不定时抛出内存溢出异常,加入-XX:+HeapDumpOnOutOfMemoryError参数,居然也没有任何反应,抛出内存溢出异常时什么文件都没有产生。无奈之下只好挂着jstat紧盯屏幕,发现垃圾收集并不频繁,Eden区、Survivor区、老年代以及方法区的内存全部都很稳定,压力并不大,但就是照样不停抛出内存溢出异常。在内存溢出后从系统日志中找到异常堆栈

问题出在直接内存,虚拟机虽然会对直接内存进行回收,但是直接内存却不能像新生代、老年代那样,发现空间不足了就主动通知收集器进行垃圾回收,它只能等待老年代满后Full GC出现后,“顺便”帮它清理掉内存的废弃对
象。否则就不得不一直等到抛出内存溢出异常时,先捕获到异常
从实践经验的角度出发,在处理小内存或者32位的应用问题时,除了Java堆和方法区之外,我们注意到下面这些区域还会占用较多的内存,这里所有的内存总和受到操作系统进程最大内存的限制:
直接内存:可通过-XX:MaxDirectMemorySize调整大小,内存不足时抛出OutOf-MemoryError或
者OutOfMemoryError:Direct buffer memory。
线程堆栈:可通过-Xss调整大小,内存不足时抛出StackOverflowError(如果线程请求的栈深度大于虚拟机所允许的深度)或者OutOfMemoryError(如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存)。
Socket缓存区:每个Socket连接都Receive和Send两个缓存区,分别占大约37KB和25KB内存,连接多的话这块内存占用也比较可观。如果无法分配,可能会抛出IOException:Too many open files异常。
JNI代码:如果代码中使用了JNI调用本地库,那本地库使用的内存也不在堆中,而是占用Java虚拟机的本地方法栈和本地内存的。
案例4:外部命令导致系统缓慢
一个数字校园应用系统,运行在一台四路处理器的Solaris 10操作系统上,中间件为GlassFish服务器。系统在做大并发压力测试的时候,发现请求响应时间比较慢,通过操作系统的mpstat工具发现处理器使用率很高,但是系统中占用绝大多数处理器资源的程序并不是该应用本身。
**原因:发现最消耗处理器资源的竟然是“fork”**系统调用。众所周知,“fork”系统调用是Linux用来产生新进程的,在Java虚拟机中,用户编写的Java代码通常最多只会创建新的线程,不应当有进程的产生,这又是个相当不正常的现象。
每个用户请求的处理都需要执行一个外部Shell脚本来获得系统的一些信息。**执行这个Shell脚本是通过Java的Runtime.getRuntime().exec()**方法来调用的。这种调用方式可以达到执行Shell脚本的目的,但是它在Java虚拟机中是非常消耗资源的操作,即使外部命令本身能很快执行完毕,频繁调用时创建进程的开销也会非常可观。Java虚拟机执行这个命令的过程是首先复制一个和当前虚拟机拥有一样环境变量的进程,再用这个新的进程去执行外部命令,最后再退出这个进程。如果频繁执行这个操作,系统的消耗必然会很大,而且不仅是处理器消耗,内存负担也很重。
**解决办法:**去掉这个Shell脚本执行的语句
案例5:服务器虚拟机进程崩溃
一个基于B/S的MIS系统,硬件为两台双路处理器、8GB内存的HP系统,服务器是WebLogic9.2(与第二个案例中那套是同一个系统)。正常运行一段时间后,最近发现在运行期间频繁出现集群节点的虚拟机进程自动关闭的现象,留下了一个hs_err_pid###.log文件后,虚拟机进程就消失了,两台物理机器里的每个节点都出现过进程崩溃的现象。从系统日志中注意到,每个节点的虚拟机进程在崩溃之前,都发生过大量相同的异常

这是一个远端断开连接的异常,通过系统管理员了解到系统最近与一个OA门户做了集成,在MIS系统工作流的待办事项变化时,要通过Web服务通知OA门户系统,把待办事项的变化同步到OA门户之中。通过SoapUI测试了一下同步待办事项的几个Web服务,发现调用后竟然需要长达3分钟才能返回,并且返回结果都是超时导致的连接中断。
由于MIS系统的用户多,待办事项变化很快,为了不被OA系统速度拖累,使用了异步的方式调用Web服务,但由于两边服务速度的完全不对等,时间越长就累积了越多Web服务没有调用完成,导致在等待的线程和Socket连接越来越多,最终超过虚拟机的承受能力后导致虚拟机进程崩溃。通知OA门户方修复无法使用的集成接口,并将异步调用改为生产者/消费者模式的消息队列实现后,系统恢复正常
案例6:不恰当数据结构导致内存占用过大
一个后台RPC服务器,使用64位Java虚拟机,内存配置为-Xms4g-Xmx8g-Xmn1g,使用ParNew加CMS的收集器组合。平时对外服务的Minor GC时间约在30毫秒以内,完全可以接受。但业务上需要每10分钟加载一个约80MB的数据文件到内存进行数据分析,这些数据会在内存中形成超过100万个HashMap<Long,Long>Entry,在这段时间里面Minor GC就会造成超过500毫秒的停顿
产生问题的根本原因是用HashMap<Long,Long>结构来存储数据文件空间效率太低了
我们具体分析一下HashMap空间效率,在HashMap<Long,Long>结构中,只有Key和Value所存放的两个长整型数据是有效数据,共16字节(2×8字节)。这两个长整型数据包装成java.lang.Long对象之后,就分别具有8字节的Mark Word、8字节的Klass指针,再加8字节存储数据的long值。然后这2个Long对象组成Map.Entry之后,又多了16字节的对象头,然后一个8字节的next字段和4字节的int型的hash字段,为了对齐,还必须添加4字节的空白填充,最后还有HashMap中对这个Entry的8字节的引用,这样增加两个长整型数字,实际耗费的内存为(Long(24byte)×2)+Entry(32byte)+HashMapRef(8byte)=88byte,空间效率为有效数据除以全部内存空间,即16字节/88字节=18%,这确实太低了
案例7:由Windows虚拟内存导致的长时间停顿
有一个带心跳检测功能的GUI桌面程序,每15秒会发送一次心跳检测信号,如果对方30秒以内都没有信号返回,那就认为和对方程序的连接已经断开。
问题:
程序上线后发现心跳检测有误报的可能,查询日志发现误报的原因是程序会偶尔出现间隔约一分钟的时间完全无日志输出,处于停顿状态
出现原因:当它最小化的时候,资源管理中显示的占用内存大幅度减小,但是虚拟内存则没有变化,因此怀疑程序在最小化时它的工作内存被自动交换到磁盘的页面文件之中了,这样发生垃圾收集时就有可能因为恢复页面文件的操作导致不正常的垃圾收集停顿。
**解决方法:**可以加入参数“-Dsun.awt.keepWorkingSetOnMinimize=true”来解决。这个参数在许多AWT的程序上都有应用,例如JDK(曾经)自带的VisualVM,启动配置文件中就有这个参数,保证程序在恢复最小化时能够立即响应。在这个案例中加入该参数,问题马上得到解决。
案例8:由安全点导致长时间停顿
有一个比较大的承担公共计算任务的离线HBase集群,运行在JDK 8上,使用G1收集器。每天都有大量的MapReduce或Spark离线分析任务对其进行访问,同时有很多其他在线集群Replication过来的数据写入,因为集群读写压力较大,而离线分析任务对延迟又不会特别敏感,所以将-XX:MaxGCPauseMillis参数设置到了500毫秒。不过运行一段时间后发现垃圾收集的停顿经常达到3秒以上,而且实际垃圾收集器进行回收的动作就只占其中的几百毫秒
user:进程执行用户态代码所耗费的处理器时间。
·sys:进程执行核心态代码所耗费的处理器时间。
·real:执行动作从开始到结束耗费的时钟时间。
请注意,前面两个是处理器时间,而最后一个是时钟时间,它们的区别是处理器时间代表的是线程占用处理器一个核心的耗时计数,而时钟时间就是现实世界中的时间计数。如果是单核单线程的场景下,这两者可以认为是等价的,但如果是多核环境下,同一个时钟时间内有多少处理器核心正在工作,就会有多少倍的处理器时间被消耗和记录下来
问题:日志中的2255毫秒自旋(Spin)时间就是指由于部分线程已经走到了安全点,但还有一些特别慢的线程并没有到,所以垃圾收集线程无法开始工作,只能空转(自旋)等待
**原因及解决方法:**最终查明导致这个问题是HBase中一个连接超时清理的函数,由于集群会有多个MapReduce或Spark任务进行访问,而每个任务又会同时起多个Mapper/Reducer/Executer,其每一个都会作为一个HBase的客户端,这就导致了同时连接的数量会非常多。更为关键的是,清理连接的索引值就是int类型,所以这是一个可数循环,HotSpot不会在循环中插入安全点。当垃圾收集发生时,如果RpcServer的Listener线程刚好执行到该函数里的可数循环时,则必须等待循环全部跑完才能进入安全点,此时其他线程也必须一起等着,所以从现象上看就是长时间的停顿。找到了问题,解决起来就非常简单了,把循环索引的数据类型从int改为long即可
相关文章:
JVM-虚拟机的故障处理与调优案例分析
案例1:大内存硬件上的程序部署策略 一个15万PV/日左右的在线文档类型网站最近更换了硬件系统,服务器的硬件为四路志强处理器、16GB物理内存,操作系统为64位CentOS 5.4,Resin作为Web服务器。整个服务器暂时没有部署别的应用&#…...
JMeter 相关的面试题
📢专注于分享软件测试干货内容,欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢交流讨论:加入1000人软件测试技术学习交流群📢资源分享:进了字节跳动之后,才…...
你在React项目中是如何使用Redux的? 项目结构是如何划分的?
一、背景 在前面文章了解中,我们了解到redux是用于数据状态管理,而react是一个视图层面的库 如果将两者连接在一起,可以使用官方推荐react-redux库,其具有高效且灵活的特性 react-redux将组件分成: 容器组件&#…...
[每周一更]-(第71期):DevOps 是什么?
Wiki的解释: DevOps(Development和Operations的混成词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。 通过自动化“软件交付”和“架构变更”的…...
k8s的安装部署,详细过程展示(保姆级安装教程)
k8s应用部署方式演变 在部署应用程序的方式上,主要经历了三个时代: 传统部署:互联网早期,会直接将应用程序部署在物理机上 优点:简单,不需要其它技术的参与 缺点:不能为应用程序定义资源使用…...
基于windows、GDAL2.2.3版本和Java集成安装和使用GDAL库的方法
基于windows、GDAL2.2.3版本和Java集成安装和使用GDAL库的方法 一、下载gdal windows版本64位2.2.3版本 下载地址: https://www.gisinternals.com/archive.php 找到gdal-202-1911-x64-core.msi下载并安装 安装后默认目录为:C:\Program Files\GDAL 二、…...
AlphaControls控件TsRadioGroup的使用
通常使用AlphaControls控件中的TsRadioGroup时,往往使用默认值,会造成TsRadioGroup标题被TsRadioGroup的ITEMs占用,严重影响美观: 解决方案,通过对TsRadioGroup的ContentVOffset属性,设置为10。即可立即改善…...
安卓常见设计模式8------享元模式(Kotlin版)
1. W1 是什么,什么是享元模式? 享元模式(Flyweight Pattern)是一种结构型设计模式,用于有效地支持大量细粒度的对象共享。在 Android 中,享元模式可以用于减少内存使用和提高性能,特别是在需…...
day54 django中orm数据库增删改查
昨日内容回顾 三板斧问题 HttpResponse # 返回的是字符串 render # 渲染一个HTML静态文件,模板文件 redirect # 重定向的 """在视图文件中得视图函数必须要接收一个形参request,并且,视图…...
【js逆向实战】某sakura动漫视频逆向
写在前面 再写一个逆向实战,后面写点爬虫程序来实现一下。 网站简介与逆向目标 经典的一个视频网站,大多数视频网站走的是M3U8协议,就是一个分段传输,其实这里就有两个分支。 通过传统的m3u8协议,我们可以直接进行分…...
L2-015 互评成绩
学生互评作业的简单规则是这样定的:每个人的作业会被k个同学评审,得到k个成绩。系统需要去掉一个最高分和一个最低分,将剩下的分数取平均,就得到这个学生的最后成绩。本题就要求你编写这个互评系统的算分模块。 输入格式…...
【Docker安装RockeMQ:基于Windows宿主机,并重点解决docker rocketMQ安装情况下控制台无法访问的问题】
拉取镜像 docker pull rocketmqinc/rocketmq创建网络 docker network create rocketmq-net构建namesrv容器 docker run -d -p 9876:9876 -v D:/dockerFile/rocketmq/namesrv/logs:/root/logs -v D:/dockerFile/rocketmq/namesrv/store:/root/store --network rocketmq-net -…...
Android Studio——android项目运行main()函数
报错: 解决: 如图,在 .idea 的 gradle.xml 中标注的位置增加如下一行代码即可<option name"delegatedBuild" value"false" />...
移动医疗科技:开发互联网医院系统源码
在这个数字化时代,互联网医院系统成为了提供便捷、高效医疗服务的重要手段。本文将介绍利用移动医疗科技开发互联网医院系统的源码,为医疗行业的数字化转型提供有力支持。 智慧医疗、互联网医院这一类平台可以通过线上的形式进行部分医疗服务ÿ…...
代码审计, 介绍, 思路总结
代码审计 一, 代码审计介绍 渗透测试中的代码审计是一个关键步骤,它涉及到深入检查应用程序的源代码,以发现安全漏洞、弱点或不合规的编码实践。这种审计通常由专业的安全工程师或渗透测试人员执行,并侧重于识别可能被黑客利用的安全缺陷。…...
2023NOIP A层联测27 总结
T1 一棵树,操作是把一个点染黑,查询点 x x x 到黑点路径上的最小编号, n ≤ 1 0 6 n\le10^6 n≤106。当时的思路是把树分成几部分,中间和周围的散块,发现不会,就没思路了,就去打了25pts暴力。赛…...
2022最新版-李宏毅机器学习深度学习课程-P34 自注意力机制类别总结
在课程的transformer视频中,李老师详细介绍了部分self-attention内容,但是self-attention其实还有各种各样的变化形式: 一、Self-attention运算存在的问题 在self-attention中,假设输入序列(query)长度是N…...
css sprite 的优缺点,使用方法和示例
CSS Sprite是一种网页图片应用处理方式。 CSS Sprite的原理是将一个网页或者一个模块所用到的零碎的icon整合拼接到一张大图里,再把这张大图作为背景图放入到网页中,当访问该页面时,加载的图片就不会像以前那样一幅一幅地慢慢显示出来了。 …...
通过Cookie和Session来实现网站中登录账号的功能
文章目录 一、Cookie和Session二、基于Cookie和Session实现登录账号的功能2.1步骤一2.2步骤二2.3步骤三2.4总结通过Cookie和Session来实现登录功能2.5运行截图 一、Cookie和Session cookie是http请求header中的一个属性,是浏览器持久化存储数据的一种机制ÿ…...
QWidget 实现九宫格图案解锁
前言 最近需要实现一个九宫格图案解锁功能,查看网上的方案,基于QWidget的方案全网搜来搜去就一篇 Qt编写自定义控件:图案密码锁, 都是炒来炒去的同一篇,代码还比较复杂,运行后在PC端还是可以的,但是运行在arm机器上,就卡顿,或者容易断开手势连接线,各种不友好,于是自…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...
