记1次生产环境java进程内存泄漏问题定位(使用Arthas)

这篇具有很好参考价值的文章主要介绍了记1次生产环境java进程内存泄漏问题定位(使用Arthas)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Arthas(阿尔萨斯)

简介 | arthas, Alibaba 开源的 Java 诊断工具,参照文档安装使用很简单,在线下载或者离线下载后解压运行,启动arthas-boot.jar,会自动扫描jps进程,根据序号选择后进入arthas界面:

tar -zxvf arthas-offline.tar.gz
cd arthas
yum install -y java
yum install -y java-1.8.0-openjdk-devel
java -jar arthas-boot.jar

java -jar arthas-boot.jar
* [1]: 105241
  [2]: 454265 test.jar

常用的是dashboard,thread命令,dashboard命令能扫面当前java进程的全局信息,包括堆栈和线程信息,

dashboard的第二个显示框Memory动态地详细展示了当前jar包的堆内存heap,非堆内存nonheap,代码缓存区code_cache,元数据空间metaspace等信息,其中heap堆内存的total总量是XMS设置的大小,除非不够用还会跟系统申请,但区间就是[Xms,Xmx],堆内存的总数+非堆内存总数+代码缓存区+元数据空间+压缩的class空间就可以理解成是占用的系统的t最小内存了,但系统内存占用肯定不止这么少;

其中第一列展示的是总堆内存的大小和占用比例,其下又分为3个区域:EC,OC,S1C,分别是新生代总空间,老年代总空间,S1总空间,EU,OU,S1U,新生代使用空间,老年代使用空间,S1使用空间,三者之和可以理解成已经使用的总的从系统那里申请的内存,arthas都会展示这个usage,

Memory    used   total   max   usage   GC 

head         248m  512m 512m 50%

 上面这个可以看出最大的head=total值,说明Xms和Xmx设置的是一样的,也就是jar包启动后就像内存申请了这么大的空间,如果两者不等,这个toal可能是介于Xms和Xmx之间的某个值的;

thread命令则是更详细的线程信息,thread命令罗列所有线程的基本信息,thread -tid,tid指的是线程id可以更详细看线程目前状态;

问题描述

生产环境中的单体应用,其运行内存达到5G,远大于jar启动时候指定的最大堆内存(512M)+非堆内存+其他,使用命令行:

# 单位是M
ps -aux |grep xxxx.jar |grep -v grep| awk '{total+=$6}; END {print total/1000}'

发现其占用内存的数值还在持续增长中,使用jstat命令查看其堆栈信息发现并没有频繁FGC,而且新生代和老年带分布正常,所以结论就是堆外内存溢出:

# 查看进程号
jps
# 查看 43063进程的gc情况,2s一次,打印5次 
jstat -gc 43063 2000 5

# EC,OC,S1C,分别是新生代总空间,老年代总空间,S1总空间
# EU,OU,S1U,新生代使用空间,老年代使用空间,S1使用空间
# YGC FGC分别是young gc和full gc的次数,fgc越小说明越稳定
# YGCT FGCT 分别是young gc和 full gc花费的时间
# MC MU是 metaspace空间,如果长期占用说明这个jar包经常使用反射和代理经常访问class的元数据信息
# jstat信息都可以通过arthas查看

该情况下可以查看进程启动的线程数,使用jstack查看该进程的线程数达到了10万+,且使用的线程方式是线程池的报错,那么问题绝大部分可能就是线程的启动占用了系统内存,造成内存泄漏;

# 查看43063进程启动的线程数
jstack -l 43063

使用arthas的thread命令查看线程池报错信息发现线程池的调度方式是:LinkedBlockingQueue,找到代码中的调度方式发现,该线程池在定时任务中,每过3分钟启动1个该线程池,活跃线程数是10;

解决办法

将该线程池改为全局的对象,被bean持有,定时任务每次拿到同1个线程池,而不是每次创建新的线程池,修改后问题修复;

JAR包相关jvm建议

1、Xms和Xmx设置一样大,让jar包在启动就能申请到最大的内存空间,减少jar包的oom概率,也防止后续不能申请到最大的内存,否则jar包会先申请Xms的内存空间,根据需要再申请;

2、垃圾回收器指定为G1GC,命令: -XX:+UseG1GC 

3、使用jdk自带工具进行jar的jvm分析:

jstat(jar stattistics monitoring tool),java统计信息监视恐惧,可以动态查看jvm的堆栈信息状态:jstat -gc pid 2000 5;

jstack(java stack trace tool),java堆栈分析工具,用于生产java应用程序的线程信息,jstack -l pid >test.txt,arthas的thread命令同样可以查看线程信息;

jhat(java heap analysis tool),java堆分析工具,使用arthas的headdump 可以导出,然后jhat查看,在web的7000端口可视化展示,能方便地找到异常的大对象;文章来源地址https://www.toymoban.com/news/detail-836719.html

到了这里,关于记1次生产环境java进程内存泄漏问题定位(使用Arthas)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用Visual Leak Detector排查内存泄漏问题

    目录 1、VLD工具概述 2、下载、安装VLD 2.1、下载VLD 2.2、安装VLD 3、VLD安装目录及文件说明

    2024年02月07日
    浏览(31)
  • centos下使用jemalloc解决Mysql内存泄漏问题

    参考: MySQL bug:https://bugs.mysql.com/bug.php?id=83047tdsourcetag=s_pcqq_aiomsg  https://github.com/jemalloc/jemalloc/blob/dev/INSTALL.md (1)ptmalloc 是glibc的内存分配管理 (2)tcmalloc 是google的内存分配管理模块 (3)jemalloc 是BSD的提供的内存分配管理 (可以 使用jemalloc优化Nginx ) 三者jemalloc和tcmall

    2024年02月11日
    浏览(34)
  • C++ || C/C++内存管理 | C++动态内存管理方式 | operator new/delete函数 | new和delete实现原理 | 定位new表达式 | 内存泄漏

    C/C++中程序内存区域大致划分六个部分: 内核空间 (用户代码不能读写)、 栈 (向下增长)、 内存映射段 (文件映射、动态库、匿名映射)、 堆 (向上增长)、 数据段 (全局数据、静态数据)、 代码段 (可执行代码、只读常量)。 各自内存区域功能 栈 ,又叫做堆栈

    2024年02月21日
    浏览(41)
  • 内存泄漏问题

            内存泄漏是一种常见的问题,它可能导致系统内存不断增加,最终耗尽可用内存。解决内存泄漏问题通常需要进行调试和分析。下面是一些可能有助于解决内存泄漏问题的步骤: 1. 监控内存使用情况: a. 使用 malloc 记录日志: 在内存分配的地方添加记录,以便跟

    2024年01月17日
    浏览(30)
  • ThreadLocal有内存泄漏问题吗

    对于ThreadLocal的原理不了解或者连Java中的引用类型都不了解的可以看一下我的之前的一篇文章Java中的引用和ThreadLocal_鱼跃鹰飞的博客-CSDN博客 我这里也简单总结一下: 1. 每个Thread里都存储着一个成员变量,ThreadLocalMap 2. ThreadLocal本身不存储数据,像是一个工具类,基于ThreadL

    2024年02月14日
    浏览(34)
  • 【JAVA】生产环境kafka重复消费问题记录

    业务系统每周都有定时任务在跑,由于是大任务因此采用分而治之思想将其拆分为多个分片小任务采用 kafka异步队列消费 的形式来减少服务器压力,每个小任务都会调用后台的c++算法,调用完成之后便会回写数据库的成功次数。今天观测到定时任务的分片小任务存在被重复消

    2024年04月12日
    浏览(31)
  • C++ map clear内存泄漏问题

    map自带的clear()函数会清空map里存储的所有内容,但如果map值存储的是指针,则里面的值不会被清空,会造成内存泄漏,所以值为指针的map必须用迭代器清空。 使用erase迭代删除 迭代器删除值为指针的map,一定要注意迭代器使用正确,一旦迭代器失效程序就会崩溃。 调用cle

    2024年02月09日
    浏览(27)
  • Java中的内存溢出与内存泄漏深度解析

    目录 引言 一. 内存溢出(Memory Overflow) 1.1 堆内存溢出 1.2 栈内存溢出 1.3 内存溢出的解决策略 1.3.1 优化对象的创建和销毁 1.3.2 调整堆内存大小 1.3.3  使用内存分析工具 1.3.4 避免创建过大的对象 1.3.5 定期清理不再使用的对象 二、 内存泄漏(Memory Leak) 2.1Java内存泄漏的典

    2024年02月19日
    浏览(47)
  • 【Go】常见的四个内存泄漏问题

    1、这里更多的是由于channel+for+select导致的,错误的写法导致了发送者或接收者没有发现channel已经关闭,任务已经结束了,却仍然在尝试输入输出https://geektutu.com/post/hpg-exit-goroutine.html 不要把map用作全局

    2024年02月13日
    浏览(34)
  • ()自定义DialogFragment以及解决其内存泄漏问题

    日常开发中,dialog是常见的功能,我们时常需要弹出来一些弹框提示用户 今天就定义了一个方便的dialog基类BaseSimpleDialogFragment, 支持快速地显示一个dialog 主要功能有: initAnimation:设置入场和出场动画 getGravity:设置dialog显示位置(屏幕上,中,下) getCanceledOnTouchOutside:点

    2024年02月15日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包