JVM 调优系列之监控工具

转载自  JVM 调优系列之监控工具

摘要: 项目部署线上之后,我们该如何基于监控工具来快速定位问题....

通过上一篇的jvm垃圾回收知识,我们了解了jvm对内存分配以及垃圾回收是怎么来处理的。理论是指导实践的工具,有了理论指导,定位问题的时候,知识和经验是关键基础,数据可以为我们提供依据。

在常见的线上问题时候,我们多数会遇到以下问题:

  • 内存泄露

  • 某个进程突然cpu飙升

  • 线程死锁

  • 响应变慢...等等其他问题。

如果遇到了以上这种问题,在线下可以有各种本地工具支持查看,但到线上了,就没有这么多的本地调试工具支持,我们该如何基于监控工具来进行定位问题?

我们一般会基于数据收集来定位,而数据的收集离不开监控工具的处理,比如:运行日志、异常堆栈、GC日志、线程快照、堆快照等。经常使用恰当的分析和监控工具可以加快我们的分析数据、定位解决问题的速度。以下我们将会详细介绍。

 

JVM 常见监控工具&指令

jps:JVM 进程状况工具

如果不指定hostid就默认为当前主机或服务器。 

命令行参数选项说明如下:

例如:

jstat:JVM 统计信息监控工具

jstat  是用于见识虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、jit编译等运行数据,它是线上定位jvm性能的首选工具。

命令格式:

参数选项:

例如:

查看 gc 情况执行:jstat-gcutil 27777

 

jinfo:Java 配置信息

命令格式:

比如:获取一些当前进程的jvm运行和启动信息。

 

jmap:Java 内存映射工具

jmap命令用于生产堆转存快照。打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。

命令格式:

参数选项:

-dump:[live,]format=b,file=<filename> 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件. 

-finalizerinfo 打印正等候回收的对象的信息.

-heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.

-histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量. 

-permstat 打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来. 

-F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效. 

-h | -help 打印辅助信息 

例如:

使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况:

使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图。

 

jhat:JVM 堆快照分析工具

jhat 命令与jamp搭配使用,用来分析map生产的堆快存储快照。jhat内置了一个微型http/Html服务器,可以在浏览器找那个查看。

不过建议尽量不用,既然有dumpt文件,可以从生产环境拉取下来,然后通过本地可视化工具来分析,这样既减轻了线上服务器压力,有可以分析的足够详尽(比如 MAT/jprofile/visualVm)等。

 

jstack:Java 堆栈跟踪工具

jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。

命令格式:

参数:

后续的查找耗费最高cpu例子会用到。

 

可视化工具

对jvm监控的常见可视化工具,除了jdk本身提供的Jconsole和visualVm以外,还有第三方提供的jprofilter,perfino,Yourkit,Perf4j,JProbe,MAT等。这些工具都极大的丰富了我们定位以及优化jvm方式。

这些工具的使用,网上有很多教程提供,这里就不再过多介绍了。对于VisualVm来说,比较推荐使用,它除了对jvm的侵入性比较低以外,还是jdk团队自己开发的,相信以后功能会更加丰富和完善。

jprofilter对于第三方监控工具,提供的功能和可视化最为完善,目前多数ide都支持其插件,对于上线前的调试以及性能调优可以配合使用。

另外对于线上dump的heap信息,应该尽量拉去到线下用于可视化工具来分析,这样分析更详细。如果对于一些紧急的问题,必须需要通过线上监控,可以采用 VisualVm的远程功能来进行,这需要使用tool.jar下的MAT功能。

 

 

应用

在线上有时候某个时刻,可能会出现应用某个时刻突然cpu飙升的问题。对此我们应该熟悉一些指令,快速排查对应代码。

CPU 飙升

1、找到最耗CPU的进程

指令:

2、找到该进程下最耗费 CPU 的线程

指令:

3、转换进制

4、过滤指定线程,打印堆栈信息

指令

可以看到是一个上报程序,占用过多cpu了(以上例子只为示例,本身耗费cpu并不高)

 

线程死锁 

有时候部署场景会有线程死锁的问题发生,但又不常见。此时我们采用jstack查看下一下。比如说我们现在已经有一个线程死锁的程序,导致某些操作waiting中。

1、查找 Java 进程 ID

指令

2、查看 Java 进程的线程快照信息

指令

从输出信息可以看到,有一个线程死锁发生,并且指出了那行代码出现的。如此可以快速排查问题。

 

OOM 内存泄露

Java堆内的OOM异常是实际应用中常见的内存溢出异常。一般我们都是先通过内存映射分析工具(比如MAT)对dump出来的堆转存快照进行分析,确认内存中对象是否出现问题。

当然了出现OOM的原因有很多,并非是堆中申请资源不足一种情况。还有可能是申请太多资源没有释放,或者是频繁频繁申请,系统资源耗尽。针对这三种情况我需要一一排查。

OOM的三种情况:

1.申请资源(内存)过小,不够用。

2.申请资源太多,没有释放。

3.申请资源过多,资源耗尽。比如:线程过多,线程内存过大等。

1、排查申请申请资源问题

查看新生代,老生代堆内存的分配大小以及使用情况,看是否本身分配过小。

从上述排查,发现程序申请的内存没有问题。

2、排查 gc

特别是fgc情况下,各个分代内存情况。

3、查找最费内存的对象

上述输出信息中,最大内存对象才161kb,属于正常范围。如果某个对象占用空间很大,比如超过了100Mb,应该着重分析,为何没有释放。

 

注意,上述指令:

4、确认资源是否耗尽

pstree 查看进程线程数量

netstat 查看网络连接数量

或者采用:

ll /proc/${PID}/fd | wc -l  // 打开的句柄数

ll /proc/${PID}/task | wc -l (效果等同pstree -p | wc -l) //打开的线程数

以上就是一些常见的jvm命令应用。

 

一种工具的应用并非是万能钥匙,包治百病,问题的解决往往是需要多种工具的结合才能更好的定位问题,无论使用何种分析工具,最重要的是熟悉每种工具的优势和劣势。这样才能取长补短,配合使用。

 

 

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

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

相关文章

写给开发者:记录日志的10个建议

尽管在写这篇博文的时候&#xff0c;我是在负责运维工作&#xff0c;不过本文主要是写给开发者的。 对我来说&#xff0c;明白如何记录日志和记录什么&#xff0c;是软件工程师必须明了的最艰巨的任务之一。之所以这么说&#xff0c;是因为这项任务与预测&#xff08;divinatio…

解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)错误

解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)错误 2018年07月23日 16:55:42 犹抱琵琶半遮面 阅读数 29677 &#xff01;&#xff01;&#xff01;此类问题出现的原因是——不细心 一般的原因 Mapper interface和xml文件的定义对应…

Java 9 中的 GC 调优基础

转载自 Java 9 中的 GC 调优基础在经过了几次跳票之后&#xff0c;Java 9终于在原计划日期的整整一年之后发布了正式版。Java 9引入了很多新的特性&#xff0c;除了闪瞎眼的Module System和REPL&#xff0c;最重要的变化我认为是默认GC&#xff08;Garbage Collector&#xf…

mysql删除索引 增加索引

使用ALTER TABLE语句创建索引alter table table_name add index index_name (column_list) ; alter table table_name add unique (column_list) ; alter table table_name add primary key (column_list) ;删除索引drop index index_name on table_name ; alter table table_n…

Hibernate基本概念 (3)

一、hibernate配置&#xff1a;1.导jar包2.配置主文件a。数据库连接 url 驱动 用户名&#xff0c;密码&#xff0c;方言b。相关 显示sql&#xff0c;sql格式化c。映射文件3.映射文件表到实体 字段到属性查询&#xff1a;select dname from Dept d;参数&#xff1a;1.按位置&…

全自动迁移数据库的实现 (Fluent NHibernate, Entity Framework Core)

在开发涉及到数据库的程序时&#xff0c;常会遇到一开始设计的结构不能满足需求需要再添加新字段或新表的情况&#xff0c;这时就需要进行数据库迁移。实现数据库迁移有很多种办法&#xff0c;从手动管理各个版本的ddl脚本&#xff0c;到实现自己的migrator&#xff0c;或是使用…

ThreadLocal 内存泄露的实例分析

转载自 ThreadLocal 内存泄露的实例分析前言 昨天分享了一篇深入分析 ThreadLocal 内存泄漏问题是从理论上分析ThreadLocal的内存泄漏问题&#xff0c;这一篇文章我们来分析一下实际的内存泄漏案例。分析问题的过程比结果更重要&#xff0c;理论结合实际才能彻底分析出内存泄…

ZKWeb网站框架的动态编译的实现原理

ZKWeb网站框架是一个自主开发的网页框架&#xff0c;实现了动态插件和自动编译功能。ZKWeb把一个文件夹当成是一个插件&#xff0c;无需使用csproj或xproj等形式的项目文件管理&#xff0c;并且支持修改插件代码后自动重新编译加载。 下面将说明ZKWeb如何实现这个功能&#xff…

Hibernate基本概念 (4)

一、缓存&#xff1a;提高性能1.一级缓存&#xff1a;session级别 一个session共享2.二级缓存&#xff1a;进程或群集级别 不同session可以共享步骤&#xff1a;1.导jar包 2.添加xml放到src3.配置hibernate.cfg.xmla.开启二级缓存b。缓存管理类4.配置持久化类使用二级缓存 3…

Java中的内存泄露的几种可能

转载自 Java中的内存泄露的几种可能Java内存泄漏引起的原因&#xff1a;内存泄漏是指无用对象&#xff08;不再使用的对象&#xff09;持续占有内存或无用对象的内存得不到及时释放&#xff0c;从而造成内存空间的浪费称为内存泄漏。长生命周期的对象持有短生命周期对象的引用…

Visual Studio“15”启动速度提升

在Visual Studio“15”开发工作的技术预览阶段&#xff0c;微软称自己的主要目标之一是改善性能。他们已经对这些改进进行过一定程度的介绍&#xff0c;最近又通过更全面的信息进一步介绍了这些变化。本文将介绍这些让VS“15”启动速度更快的改进。 更快速地启动VS“15” 微软项…

介绍Java中的内存泄漏

转载自 介绍Java中的内存泄漏Java语言的一个关键的优势就是它的内存管理机制。你只管创建对象&#xff0c;Java的垃圾回收器帮你分配以及回收内存。然而&#xff0c;实际的情况并没有那么简单&#xff0c;因为内存泄漏在Java应用程序中还是时有发生的。 下面就解释下什么是内存…

2-6 基于SpringBoot的SpringSecurity环境快速搭建与验证

springboot是基于spring的一套全新的框架&#xff0c;其目的是为了简化spring的初始搭建和开发过程&#xff0c;不需要再做样板话的配置了 https://start.spring.io/ 上面这些都不想做权限拦截

DotLiquid模板引擎简介

DotLiquid是一个在.Net Framework上运行的模板引擎&#xff0c;采用Ruby的Liquid语法&#xff0c;这个语法广泛的用在Ruby on rails和Django等网页框架中。DotLiquid相比于Mvc默认模板引擎Razor的好处有&#xff1a; 因为不需要编译到程序集再载入首次渲染速度很快不会导致内存…

Hibernate基本概念 (5)

-----模板1.一对多(set)<set name"属性"><key column"关系外键"/><one-to-many class"实体类全名称"/></set>2.多对一<many-to-one name"" class"" column"关系外键"/>3.多对多(s…

Vue 阻止事件冒泡

转载自 Vue2学习笔记:事件对象、事件冒泡、默认行为1.事情对象<!DOCTYPE html> <html> <head><title></title><meta charset"utf-8"><script src"http://unpkg.com/vue/dist/vue.js"></script><scrip…

Windows Server 2016及System Center 2016正式商用

Windows Server 2016 及 System Center 2016 现已正式商用。作为微软全新一代的服务器操作系统和数据中心管理平台&#xff0c;它们将为企业 IT 带来全面的性能与安全性提升&#xff1b;为数据中心、私有云及公有云环境提供一致的混合云管理平台&#xff1b;并为在本地和云端开…

2-7 SpringBoot常用注解讲解

首先&#xff0c;讲解一下RestController RestController RestController是Controller和ResponseBody的结合。 RnableAutoConfiguration EnableAutoConfiguration springboot建议只能有一个有该注解的类 这个注解的作用是 根据你配置的依赖自动配置 根据jar包的配置…

vue-beauty UI库

vue-beauty UI库文档地址 一、全局配置全局CSS样式Polyfill二、组件&#xff08;1&#xff09;普通Button 按钮Icon 图标&#xff08;2&#xff09;布局Grid 栅格Layout 布局MorePanel 更多条件&#xff08;3&#xff09;导航Affix 固钉Breadcrumb …

ArrayList整理

ArrayList整理1&#xff0c;ArrayList特性2,ArrayList底层实现的特征1)&#xff0c;ArrayList初始化2)&#xff0c;初始容量3)&#xff0c;ArrayList的添加元素的add()方法4&#xff09;&#xff0c;ArrayList的删除方法remove(int index)其他的一些方法的操作其实都差不多&…