jStat

JVM故障诊断和处理工具

旧街凉风 提交于 2021-01-14 20:15:20
本文已被Github仓库收录 https://github.com/silently9527/JavaCore 微信公众号:贝塔学Java 前言 前几天中午正在和同事最近聊股市较好,这几天每天都可以喝点肉汤,心里还是挺高兴的;正在这个时候收到了线上告警邮件和运维同学的消息,“你们有服务挂了!”,心里一紧,立马打开电脑看来下线上cat监控大盘,发现很多服务都在报错,根据cat上的监控日志很快发现了其中一个服务内存溢出导致其他调用服务也有问题,竟然已经定位到了出问题的服务,那就简单了,没有是重启解决不了的问题,重启之后很快服务都恢复正常了。几分钟之后又报错了,同样也是这个服务内存溢出,经过排查后发现该服务的堆内存被改小了,好家伙,运维同学不讲武德,搞偷袭,趁我没反应过来调了内存,内存调整回去之后服务就恢复了正常。 事后把线上的快照文件拖了下来分析,发现本身这个项目的代码也有些问题,本文就整理了一下JVM常用的分析工具。 命令行工具 在安装完JDK之后在JAVA_HOME/bin目录下JDK已经提供了很多命令行的工具 可能我们最常用的就是 java 、 javac 这两个命令,除了这两个命令之外还有提供很多其他的实用工具,本文主要来一起学习对JVM监控诊断工具 虚拟机进程状况工具(jps) 该工具的功能比较单一,与linux中的ps功能类似,用来列出正在运行的虚拟机进程

JVM之JDK命令行工具

送分小仙女□ 提交于 2021-01-04 03:37:07
JDK 内置了许多命令行工具,可用来获取JVM 不同层面的信息;例如: 工具 作用 场景 jps 查看当前java进程、传递参数 查看PID: jps -l 、查看给jvm传递的参数: jps -l -v jstack 查看java进程内的线程堆栈信息,可用来检测死锁、死循环飙高CPU等。 参见: https://my.oschina.net/u/3457546/blog/1930546 jmap 查看堆各区域的使用情况以及配置信息。 查看堆配置:jmap -heap PID 、查看堆中存活对象:jmap -histo:live PID jinfo 查看和调整JVM的各项参数配置。 查看所有参数:jinfo PID、查看设置过值的参数: jinfo -flags PID 运行过程中动态开启GC日志等 jstat JVM监控工具,Java进程的类加载、垃圾收集、内存使用等信息。 每1000毫秒输出一次java的垃圾回收信息,总共10次:jstat -gc -h3 PID 1000 10 jcmd JDK1.7之后的JVM诊断工具,是一个多功能工具,可用于获取进程的性能统计、内存使用、垃圾收集、线程堆栈、JVM 运行时间等信息;可以理解为上面的命令集成版。 jps 查看PID以及指定参数 通过jps命令配合相关参数可以查看java进程相关信息 #-l参数用来查看端口号和包名 [root

记一次 CMS 回收异常问题 —— 跨代引用和循环依赖

梦想的初衷 提交于 2021-01-02 15:23:54
模型系统加载深度学习模型后,会触发报警,原因是触发了 Full GC,而 GC 后回收效率却不高,回收前 83%,回收后 65%,老年代加载完成单率模型后,竟然从 150M 飙到了 1.5G 以上,而实际上用 jol 计算出来的模型大小才 300M,这明显是不符合预期的。最后排查发现实际是 跨代引用和循环依赖 导致的问题。 GC 日志 GC日志 整理如下: 服务启动 1 YGC,from survivor 占用 64% - 0.59s 2 YGC,from survivor 占用 24%,有 165823K 进入老年代,被回收的不多,差不多 10M - 0.43s 3 YGC,from survivor 占用 10%,老年代使用了 165823K,结果没变,但是发现 eden 区没有用满就触发 Young GC 了,Eden 区用了 47% - 0.03s 【这个过程是在 Full GC 之前,可以看到触发条件是 System.gc()】 - 初始标记 0.01s STW - 并发标记 0.03s - 并发预清理 0.01s + 5.4s - 最后标记 0.11s STW - 并发清理 0.15s - 并发重启 0.04s 也就是说这次 Full GC 有 0.12s 会 Stop the world,而最后老年代还剩余 165820K,回收了 3K 4 YGC,from

服务器性能指标——负载(Load)分析及问题排查

我们两清 提交于 2020-12-26 16:57:29
平常的工作中,在衡量服务器的性能时,经常会涉及到几个指标,load、cpu、mem、qps、rt等。每个指标都有其独特的意义,很多时候在线上出现问题时,往往会伴随着某些指标的异常。大部分情况下,在问题发生之前,某些指标就会提前有异常显示。 对于这些指标的理解和查看、异常解决等,是程序员们重要的必备技能。本文,主要来介绍一下一个比较重要的指标——机器负载(Load),主要涉及负载的定义、查看负载方式、负载飙高排查思路等。 什么是负载 随着 Internet 的快速发展和业务量的不断提高,基于网络的数据访问流量迅速增长,特别是对数据 中心、大型企业以及门户网站等的访问,其访问流量甚至达到了 10Gb/s 的级别;同时,服务器网 站借助 HTTP、FTP、SMTP 等应用程序,为访问者提供了越来越丰富的内容和信息,服务器逐渐 被数据淹没;另外,大部分网站(尤其电子商务等网站)都需要提供不间断 24 小时服务,任何服 务中断或通信中的关键数据丢失都会造成直接的商业损失。所有这些都对应用服务提出了高性能和 高可靠性的需求,这些海量的访问数据均是负载。 查看机器负载 在Linux机器上,有多个命令都可以查看机器的负载信息。其中包括 uptime 、top、w 等。 uptime 命令 命令能够打印系统总共运行了多长时间和系统的平均负载。uptime命令可以显示的信息显示依次为:现在时间

JVM(java 虚拟机)

生来就可爱ヽ(ⅴ<●) 提交于 2020-12-25 03:27:01
JVM(java 虚拟机) 一.JVM简介 1.JVM:Java Virtual Machine (java 虚拟机) 通过软件来模拟出来的具有完整的硬件系统功能、运行在完全隔离的环境中的完整的计算机系统。 2.种类: 1)Sun Classic 经典款 2)Exact VM 准确式内存管理 3)Sun HotSpot VM 热代码跟踪 二.JVM运行时的区域 1.运行时的区域 2.线程隔离区域(程序计数器、java栈) 程序计数器:是当前线程所执行的字节码的行号指示器,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。 为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,所以程序计数器这类内存区域为“线程私有的内 如果线程正在执行的是Native方法,这个计数器的值为空。 3.java 栈 执行代码的内存区域,比如执行方法,变量,引用等。包括:java虚拟机栈、本地方法栈;他们作用相似,区别只是:虚拟机栈为虚拟机执行java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。 栈里存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long

一次 Java 内存泄漏的排查

若如初见. 提交于 2020-12-25 03:26:35
由来 前些日子小组内安排值班,轮流看顾我们的服务,主要做一些报警邮件处理、Bug 排查、运营 issue 处理的事。工作日还好,无论干什么都要上班的,若是轮到周末,那这一天算是毁了。 不知道是公司网络广了就这样还是网络运维组不给力,网络总有问题,不是这边交换机脱网了就是那边路由器坏了,还偶发地各种超时,而我们灵敏地服务探测服务总能准确地抓住偶现的小问题,给美好的工作加点料。好几次值班组的小伙伴们一起吐槽,商量着怎么避过服务保活机制,偷偷停了探测服务而不让人发现(虽然也并不敢)。 前些天我就在周末处理了一次探测服务的锅。 转载随意,文章会持续修订,请注明来源地址: https://zhenbianshu.github.io 。 问题 网络问题? 晚上七点多开始,我就开始不停地收到报警邮件,邮件显示探测的几个接口有超时情况。 多数执行栈都在: java.io.BufferedReader.readLine(BufferedReader.java:371) java.io.BufferedReader.readLine(BufferReader.java:389) java_io_BufferedReader$readLine.call(Unknown Source) com.domain.detect.http.HttpClient.getResponse(HttpClient

一次 Java 内存泄漏的排查

微笑、不失礼 提交于 2020-12-24 01:51:30
由来 前些日子小组内安排值班,轮流看顾我们的服务,主要做一些报警邮件处理、Bug 排查、运营 issue 处理的事。工作日还好,无论干什么都要上班的,若是轮到周末,那这一天算是毁了。 不知道是公司网络广了就这样还是网络运维组不给力,网络总有问题,不是这边交换机脱网了就是那边路由器坏了,还偶发地各种超时,而我们灵敏地服务探测服务总能准确地抓住偶现的小问题,给美好的工作加点料。好几次值班组的小伙伴们一起吐槽,商量着怎么避过服务保活机制,偷偷停了探测服务而不让人发现(虽然也并不敢)。 前些天我就在周末处理了一次探测服务的锅。 转载随意,文章会持续修订,请注明来源地址: https://zhenbianshu.github.io 。 问题 网络问题? 晚上七点多开始,我就开始不停地收到报警邮件,邮件显示探测的几个接口有超时情况。 多数执行栈都在: java . io . BufferedReader . readLine ( BufferedReader . java : 371 ) java . io . BufferedReader . readLine ( BufferReader . java : 389 ) java_io_BufferedReader$readLine . call ( Unknown Source ) com . domain . detect . http

[JVM工具(1)] 堆栈检查利器jstat的使用

会有一股神秘感。 提交于 2020-12-19 00:19:25
jstat 可以检查 JVM 整体的运行情况,可以看到 新生代,老年代等的内存使用情况,以及 GC 次数和耗时 命令格式 如 jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]] 其中 -option 必选参数表示命令参数 如 gc 等, -t 为可选参数表示是否打印时间(秒), -h<lines> 可选参数,表示每隔多少行打印头部列表,如设置 -h 5 , 那么每五条记录就会重新打印表头, vmid 必选参数, Java 进程 id , interval 可选参数表示采样的时间间隔, count 可选参数表示需要采样多少条, jstat -gc pid jstat -gc pid 这是最常用的语法,可以直接查看内存和垃圾回收情况 首先我们要获得 Java 进程的 PID 信息,可以通过 jps 命令来获取 之后执行 jstat -gc pid 即可看到对应 Java 进程的内存情况,如下: 这里说明一下关于这些列名的含义 : S0C : 新生代中第一个 Survivor (即 From 区)的容量大小 (千字节) S1C : 新生代中第二个 Survivor (即 To 区)的容量大小 (千字节) S0U : 新生代 From Survivor 区已使用内存大小(千字节) S1U : 新生代 To

几款Java开发者必备常用的工具,准点下班不在话下

若如初见. 提交于 2020-12-18 13:49:45
摘要 :一问一答的形式轻松学习掌握java工具。 以一问一答的形式学习java工具 Q:检查内存泄露的工具有? A: jmap生成dump转储文件,jhat可视化查看。 Q:某进程CPU使用率一直占满,用什么工具可以排查? A: top -Hp pid找到最占CPU的线程 然后jstack来查找那个线程此时所处的堆栈,确定问题发生位置。 § 各工具详细介绍 § jstack 全称: JVM Stack Trance 作用: 查看某个java进程的堆栈情况, 可用于确认死锁、IO等待、死循环等问题。 命令用法: jstack pid 查看死锁例子如下图,找到wait的lock和已被锁的lock 查看等待IO例子: § jstat 全称: 作用: 查看进程中内存使用情况,但只能给出一些简单统计数据 统计加载了多少类以及占用空间 jstat -class pid 统计编译了多少文件 jstat -compiler 10 Q: jstat -gcutil {pid} 2000 可以每隔2秒,对pid进程打印内存使用统计信息。 gcutil的输出如下 里面哪个百分比如果长期处于99%-100%会有OMM风险?(OutOfMemoryError) A: 如果E和O即新生代、老年代内存区一直都处于满的状态,则很有可能会引发OMM风险。就像下面这个。 § jmap 全称: JVM Memory

JVM系列之:内存与垃圾回收篇(二)

牧云@^-^@ 提交于 2020-12-07 18:23:24
JVM系列之:内存与垃圾回收篇(二) ##本篇内容概述: 1、堆Heap Area 2、方法区Method Area 3、运行时数据区总结 4、对象的实例化内存布局和访问定位 一、堆 Heap Area 1、堆的核心概念 ·一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域。 ·Java堆区在JVM启动的时候即被创建,其空间大小也就被确定下来了。是JVM管理的最大一块内存空间。 ·堆可以处于物理上不连续的内存空间中,但在逻辑上他应该被视为连续的。 ·所有的线程共享Java堆,在这里还可以划分线程私有的缓冲区TLAB(Thread Local Allocation Buffer) 【所以说堆空间不是完全共享的,因为还有TLAB】 ·堆内存的大小是可以调节的:初始堆空间-Xms10m 最大堆空间-Xmx10m ##解释: 一个进程对应一个JVM实例,一个JVM实例对应一个Runtime Data Area, 一个进程对应一个堆和方法区,一个进程有多个线程,每个线程对应一个PC寄存器、虚拟机栈和本地方法栈。 因此,堆和方法区在进程中会被多个线程共享。 ·几乎所有的对象实例 以及 数组 都应该在运行时分配在堆上。 ·数组和对象可能永远不会存储在栈上,因为栈帧中保存应用,这个引用指向对象或者数组在堆中的位置。 ·在方法结束后,堆中的对象不会马上被移除