【JVM】一次JVM内存泄露分析处理

一次内存泄露分析

背景情况

编写了一个大数据基础组件的可用性监控程序,采用Bootstrap监测端口的方式,使得方法常驻(main线程常驻),通过一个调度线程ScheduledThreadPoolExecutor,定时的调动监测任务。

监测任务中,通过一个工作的线程池,执行Callable<?> 的任务,每个组件的检测一个Callable Task。要求每个检测带回检测结果,所以使用了Callable。

定时调度的监测任务

public void run() {try {boolean alertFlag = false;long t1 = System.currentTimeMillis();StringBuilder htmlBody = new StringBuilder();for (Monitor monitor : monitorList) {// 返回数据结果Map中有两个值, 一个key为componentName,值为组件的名称;一个key为组件的名称.值为此组件连续发生异常的数量final Future<?> future =ThreadPool.submitTask(() -> {Map<String, String> map = new HashMap<>();StringBuilder result = new StringBuilder();result.append(HTML_BR).append("【").append(monitor.getName()).append("】").append(HTML_BR);try {result.append(monitor.monitor());} catch (Exception e) {result.append(MonitorSupport.ERROR_INFO).append(HTML_BR);componentExceptionNum.put(monitor.getName(), componentExceptionNum.get(monitor.getName()) + 1);LOGGER.error("{}执行异常", monitor.getName(), e);} finally {map.put(monitor.getName(), result.toString());map.put(MONITOR_RESULT_KEY, monitor.getName());}return map;});list.add(future);}// 执行的最大时长应该是监控任务调度的周期也就是monitorInterval,// 后期优化思路:在快要超时的前1分钟,将未完成的任务取消cancel(true),快速返回。do {Iterator<Future<?>> it = list.iterator();while (it.hasNext()) {Future<?> e = it.next();try {@SuppressWarnings("unchecked")Map<String, String> map = (HashMap<String, String>) e.get(5, TimeUnit.MINUTES);if (e.isDone()) {try {if (map.get(map.get(MONITOR_RESULT_KEY)).contains(MonitorSupport.ERROR_INFO)) {htmlBody.insert(0, map.get(map.get(MONITOR_RESULT_KEY)));Integer newComponentExceptionNum = componentExceptionNum.get(map.get(MONITOR_RESULT_KEY)) + 1;if (newComponentExceptionNum >= alertThreshold.get(map.get(MONITOR_RESULT_KEY))) {alertFlag = true;} else {componentExceptionNum.put(map.get(MONITOR_RESULT_KEY), newComponentExceptionNum);}if (ComponentEnum.HBASE.getName().equals(map.get(MONITOR_RESULT_KEY))&& map.get(map.get(MONITOR_RESULT_KEY)).contains(MonitorSupport.HBASE_RESTORE_SETTINGS_ERROR)) {alertFlag = true;}} else {componentExceptionNum.put(map.get(MONITOR_RESULT_KEY), 0);htmlBody.append(map.get(map.get(MONITOR_RESULT_KEY)));}String a = map.get(map.get(MONITOR_RESULT_KEY));LOGGER.info("执行结果={}.", a);} catch (Exception ex) {LOGGER.error("执行结果获取异常", ex);}it.remove();} else {LOGGER.warn("{}执行超时", map.get(MONITOR_RESULT_KEY));e.cancel(true);makeTimeOutInfo(htmlBody);alertFlag = true;it.remove();}e.cancel(true);} catch (Exception e1) {LOGGER.error("执行异常", e1);}}} while (!list.isEmpty());long t3 = System.currentTimeMillis();LOGGER.info("Monitoring spent total time: [{}]ms.", (t3 - t1));htmlBody.append("<div><br/></div>");if (LOGGER.isDebugEnabled()) {LOGGER.debug("检查结果:{}{}{}", HTML_HEAD, htmlBody, HTML_FOOD);}// 异常邮件告警if (alertFlag) {SNEmail.sendHtmlEmail(HTML_HEAD + htmlBody + HTML_FOOD);LOGGER.warn("resetComponentExceptionNum");resetComponentExceptionNum(mcs, componentExceptionNum);}} catch (Exception e) {LOGGER.warn("未处理异常异常。", e);}}

问题现象

第一次现象:执行的时候,主线程没有报错,监测任务无法调度起来了。对监测任务增加了外部的try catch,看看是不是异常被吞掉了。

第二次现象:等待了近一个月(缓慢泄露,最为致命),出现了,大量OOM(Java heap space)的报错。堆内存溢出了。

内存问题分析

使用MAT( Eclipse Memory Analysis Tools )工具进行分析。下载安装参考:使用MAT进行内存问题定位

查询java默认采用的垃圾回收器的命令:

java -XX:+PrintCommandLineFlags -version

查询某个java进程采用的垃圾回收器的命令:

12910是pid

jcmd 12910 VM.flags

结果

12910:
-XX:CICompilerCount=12 -XX:ConcGCThreads=3 -XX:G1HeapRegionSize=2097152 -XX:GCLogFileSize=33554432 -XX:InitialHeapSize=4294967296 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=2575302656 -XX:MinHeapDeltaBytes=2097152 -XX:NumberOfGCLogFiles=5 -XX:+PrintAdaptiveSizePolicy -XX:+PrintGC -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:+UseGCLogFileRotation

-XX:+UseG1GC参数来启用G1GC。

jmap生存内存快照

./jmap -dump:format=b,file=/opt/logs/java_pid27258.hprof 27258

利用MAT生成报告

相关命令:./ParseHeapDump.sh java_pid27258.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components,执行命令的用户需要配置jdk(用的JDK8)

报告分析

​ 产生三个文件java_pid27258_Leak_Suspects.zip,java_pid27258_System_Overview.zip ,java_pid27258_Top_Components.zip

查看占用内存对象中高占比的对象Top Consumers

在这里插入图片描述

查询溢出原因猜测Leak Suspects

在这里插入图片描述

猜想

看这个对象,应该是ES客户端的Sniff线程。使用RestHighLevelClient使用为了实现节点嗅探增加的Sniff。

处理

尝试了highLevelClient.close()highLevelClient.getLowLevelClient().close(),发现这个Sniff线程竟然关不掉。关不掉,又在不停创建新的客户端,那肯定会出现内存溢出了。由于监控ES是不停的创建新ES客户端,并非以保证长连接的要求去实现的。所以去掉了了Sniff功能。

以下是开启Sniff的写法。

    private RestHighLevelClient initRestHighLevelClientByIp(String ip, Integer port) {HttpHost[] httpHosts = buildHttpHosts(ip, port);// 开启嗅探SniffOnFailureListener sniffOnFailureListener = new SniffOnFailureListener();RestHighLevelClient highLevelClient = new RestHighLevelClient(RestClient.builder(httpHosts).setFailureListener(sniffOnFailureListener));// 嗅探器可以通过setSniffIntervalMills(以毫秒为单位)更新一次节点列表,Sniffer sniffer = Sniffer.builder(highLevelClient.getLowLevelClient()).setSniffAfterFailureDelayMillis(5 * 60000).build();sniffOnFailureListener.setSniffer(sniffer);return highLevelClient;}

重新启动程序。观察内存变化(多次jmap,看生成的hprof文件的大小变化)。

再次使用MAT生成内存报告,查询泄露情况

在这里插入图片描述

发现有java.lang.ref.Finalizer的占比挺高的、但是JVM垃圾回收处于正常运行了。

TODO 什么是java.lang.ref.Finalizer,下次分析学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/18139.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

adb获取包名和界面名

adb获取包名和界面名 mac adb shell dumpsys window windows | grep mFocusedApp windows adb shell dumpsys window windows | findstr mFocusedApp 这个是在当前手机打开哪个界面获取的就是哪个界面的包名与界面 注意第一次连接时会有提示&#xff0c;需要连接两次才可以 …

【AI算法岗面试八股面经【超全整理】——机器学习】

AI算法岗面试八股面经【超全整理】 概率论信息论机器学习深度学习CVNLP 目录 1、回归损失函数2、分类损失函数3、误差&#xff08;Error&#xff09;、偏差&#xff08;Bias&#xff09;、方差&#xff08;Variance&#xff09;4、PCA&#xff08;Principle Component Analysi…

四川汇聚荣聚荣科技有限公司好不好?

在当今科技飞速发展的时代&#xff0c;企业要想在激烈的市场竞争中脱颖而出&#xff0c;必须具备强大的技术实力和良好的市场口碑。那么&#xff0c;作为一家专注于科技创新的公司&#xff0c;四川汇聚荣聚荣科技有限公司究竟如何呢?接下来&#xff0c;我们将从四个方面进行详…

扔掉 MacBook,挑战带OrangePi出差!

背景 由于工作需要&#xff0c;博主经常会到各大企业的自建机房中私有化部署公司的软件产品。 在某些企业自建机房中&#xff0c;有时给到全新的机器&#xff0c;没有基础环境&#xff0c;甚至有的还无法互联网&#xff0c;而且因为近几年CentOS的停止更新&#xff0c;服务器…

【Linux】Linux的权限_2 + Linux环境基础开发工具_1

文章目录 三、权限3. Linux权限管理修改文件的拥有者和所属组 4. 文件的类型5. 权限掩码 四、Linux环境基础开发工具1. yumyum 工具的使用 未完待续 三、权限 3. Linux权限管理 修改文件的拥有者和所属组 在上一节我们讲到如何更改文件的访问权限&#xff0c;那我们需要更改…

光伏智慧化运营解决方案的应用和价值

在社会对新能源需求的不断扩大&#xff0c;光伏已经成为了可再生能源的重要组成部分&#xff0c;随着光伏电站数量和规模的不断扩大&#xff0c;相关企业和用户都就开始关注如何能够高效精准的进行电站管理&#xff0c;对此&#xff0c;鹧鸪云提出了光伏智慧化运营解决方案&…

【官方指南】3ds Max中纹理贴图问题及正确解决方案

在使用3ds Max进行设计和制作时&#xff0c;纹理贴图是一个非常重要的环节。然而&#xff0c;许多用户在使用过程中常会遇到各种纹理贴图问题。为此&#xff0c;Autodesk官方提供了一些有效的解决方案&#xff0c;可以解决90%的纹理贴图难题。这里小编都帮大家整理好了&#xf…

简化跨网文件传输摆渡过程,降低IT人员工作量

在当今数字化时代&#xff0c;IT企业面临着日益增长的数据交换需求。随着网络安全威胁的不断演变&#xff0c;网关隔离成为了保护企业内部网络不受外部威胁的重要手段。然而&#xff0c;隔离的同时&#xff0c;企业也需要在不同网络间安全、高效地传输文件&#xff0c;这就催生…

线性回归计算举例

使用正规方程计算&#xff08;一元线性回归&#xff09; import numpy as np import matplotlib.pyplot as plt # 转化成矩阵 X np.linspace(0, 10, num 30).reshape(-1, 1) # 斜率和截距&#xff0c;随机生成 w np.random.randint(1, 5, size 1) b np.random.randint(1,…

Qt项目使用pato mqtt C

一,下载pato mqtt C 源码 git 地址:https://github.com/eclipse/paho.mqtt.c.git git 地址可能下载不下来,提供我的gitee地址 gitee地址:https://gitee.com/chaojidahuaidan2021/paho.mqtt.c.git 二,编译共享库 clone下来后,将项目导入到Qt工程中,此时这是一个cmke工程…

三十一、openlayers官网示例Draw Features解析——在地图上自定义绘制点、线、多边形、圆形并获取图形数据

官网demo地址&#xff1a; Draw Features 先初始化地图&#xff0c;准备一个空的矢量图层&#xff0c;用于显示绘制的图形。 initLayers() {const raster new TileLayer({source: new XYZ({url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/…

Kubernetes和Docker对不同OS和CPU架构的适配关系

Docker Docker官网对操作系统和CPU架构的适配关系图 对于其他发行版本&#xff0c;Docker官方表示没有测试或验证在相应衍生发行版本上的安装&#xff0c;并建议针对例如Debian、Ubuntu等衍生发行版本上使用官方的对应版本。 Kubernetes X86-64 ARM64 Debian系 √ √ Re…

贪心算法[1]

首先用最最最经典的部分背包问题来引入贪心的思想。 由题意可知我们需要挑选出价值最大的物品放入背包&#xff0c;价值即单位价值。 我们需要计算出每一堆金币中单位价值。金币的属性涉及两个特征&#xff0c;重量和价值。 所以我们使用结构体。 上代码。 #include <i…

【debug】windows11安装WSL+Docker+本地部署cvcat

windows系统安装wsl虚拟机 首先观察是否已启用虚拟化&#xff1a; 在windows应用商店下载wsl 下载好后打开&#xff0c;创建用户名和密码&#xff0c;即可使用&#xff1a; 换源&#xff1a;ubuntu | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirr…

LeetCode215数组中第K个最大元素

题目描述 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 解析 快速排序的思想&#xff…

C++:vector的介绍及使用

✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来! 文章目录 文章目录 前言 一、vector的介绍 二、vector的使用 2.1.构造和赋值重载&#xff08;Member functions&#xff09; 2.2 vector iterator 的使用 2.3 vector 空间增长问题 2.4 vector 增删查改 三 sort 四 v…

所以研究生有不变胖的吗?

天天吃 记得和骏骏一样减肥 分享昨天无人机拍的照片

FL Studio v21.2.3.4004中文破解版百度网盘下载

FL Studio v21.2.3.4004中文破解版是一款完整的软件音乐制作环境或数字音频工作站 (DAW)。代表了超过 18 年的创新发展&#xff0c;它在一个软件包中提供了您创作、编曲、录制、编辑、混音和掌握专业品质音乐所需的一切。FL Studio v21.2.3.4004中文破解版现在是世界上最受欢迎…

长三角智能科技高端盛会—南京人工智能展览会(南京智博会)

南京&#xff0c;作为一座历史悠久的文化名城&#xff0c;早已不仅仅以其深厚的文化底蕴和独特的自然风貌著称于世。而今&#xff0c;这座古老而又年轻的城市&#xff0c;正以其卓越的科技实力和创新精神&#xff0c;成为中国乃至全球科研领域的一颗璀璨明珠。南京不仅是中国三…