Java应用性能监控系统

使用JMX(Java Management Extensions)简易实现,提供对类加载监控、内存监控、线程监控。获取Java应用本地JVM内存、GC、线程、Class、堆栈、系统数据等。

参考了Java内置的同样使用JMX(Java Management Extensions)实现的监控工具 jconsole,通过JMX系统的MXBean接口,快速获取Java应用JVM数据。

文档

更多将在我的公众号 程序员涂陌 中陆续发布,请持续关注!

程序员涂陌

捐赠

Alipay

WechatPay

JMX

JDK内置了一些监控JVM的API接口,就是java.lang.management包,其中提供了很多MXBean的接口类用来监控JVM的数据。并且JDK也内置了很多工具用于监控Java应用,其中jconsole就是使用JMX实现的,

名称

解释

ClassLoadingMXBean

获取类装载信息,已装载、已卸载量

CompilationMXBean

获取编译器信息

GarbageCollectionMXBean

获取GC信息,但他仅仅提供了GC的次数和GC花费总时间

MemoryManagerMXBean

提供了内存管理和内存池的名字信息

MemoryMXBean

提供整个虚拟机中内存的使用情况

MemoryPoolMXBean

提供获取各个内存池的使用信息

OperatingSystemMXBean

提供操作系统的简单信息

RuntimeMXBean

提供运行时当前JVM的详细信息

ThreadMXBean

提供对线程使用的状态信息

垃圾回收算法

标记-清除算法

如果两个对象间发生引用,那么就将未关联任何引用的对象标记,最后统一回收。缺点:会造成大量不连续的内存碎片。

复制算法

将整个堆内存分为等大小的两块空间,每次仅适用其中的一块。当发生垃圾回收时,将A区中仍存活的对象复制到B区,然后清空A区。缺点:虽然避免了标记-清除算法那样产生大量不连续的内存碎片,但要将整块内存分为两部分代价太大。

标记-整理算法

和标记-清除算法类似,都对为关联任何引用的对象标记,但在清除时不直接回收对象,而是将所有存活的对象移动到一端(端点处),最后直接清除端边界以外的内存。特点:解决了标记-清除算法产生大量不连续碎片问题,同时解决复制算法对内存分为两块代价太高的问题。

分代收集算法

将整块堆内存分为:新生代、老年代、元数据区(JDK1.7前叫持久区);其中新生代细分为Eden、Survivor0、Survivor1三块区域。

进入堆内存的对象首先分配在新生代(主要是Eden、Survivor0区,默认Eden:Survivor=8:1),当新生代发生垃圾回收时(Minor GC):GC首先回收新生代,将Eden、Survivor0区中仍存活的对象复制到Survivor1区,如果Survivor1区内存不够就将对象直接存放到老年代;如果老年代内存满了就触发Major GC(Full GC,即新生代、老年代都回收)。

元数据区(JDK1.7前叫持久代)主要存放静态文件、Java类、方法等,也称为方法区。持久代和元数据区区别:持久代使用的JVM的堆内存区域;而元数据区直接使用的本地的物理内存。

HotSpot算法实现

可达性分析算法

可达性分析算法主要思想:将内存中的所有对象都分别用一个个节点表示,如果对象之间存在引用那么这两个节点就相互关联;并且存在一个起始节点(GC Roots),如果一个对象顺着应用链不能到达GC Roots时(即不可达),这个对象就被判定为死亡,应该被GC回收。

可作为GC Roots的对象:

虚拟机栈(栈帧的本地变量表)中引用的对象。

方法区中类静态属性引用的对象

方法区中常量引用的对象

本地方法栈中Native方法引用的对象

HotSpot

问题引入

HotSpot使用了可达性分析算法判定对象的存活,但依次从GC Root引用链向下寻找对象未免太耗时。

解决办法

HotSpot通过一组OopMap对象记录每个节点引用位置,通过OopMap对象可以准确的知道GC Roots引用链上的引用关系,以此快速判断对象的存活。

问题引入

HotSpot通过指令生成OopMap对象记录对象引用位置,但大量的对象必然需要大量的OopMap对象,也会占用大量的内存空间。

解决办法

HotSpot并不大量生成OopMap对象,而只在特殊位置(称为安全点 Safepoint)生成OopMap对象记录引用链上对象的引用关系,此时GC的发生场所就受到限制,只有在安全点(Safepoint)处才中断线程进行GC。

垃圾收集器

串行收集器

特点

它仅仅使用单线程进行垃圾回收

它是独占式的垃圾回收

进行垃圾回收时,Java应用程序占用的线程都要暂停等待GC回收(Stop-The-World)

举例

Serial -- 单线程(串行)收集器,新生代、老年代收使用串行回收。新生代采用复制算法,老年代采用标记-整理算法

其中众多收集器中只有Serial收集器是单线程(串行)收集器。

并行收集器

特点

多线程(并行)回收

垃圾回收时,同样会暂停应用线程,但不是Stop-The-World;因为使用多线程在多核CPU上,应用线程可能与垃圾回收线程同时进行。

举例

ParNew -- 新生代多线程(并行)收集器;只作用与新生代。启用该收集器(-XX:+UseParNewGC),新生代采用复制算法,老年代默认使用Serial(串行)收集器(即使用标记-整理算法)

Parallel Scavenge -- 新生代多线程(并行)收集器;只作用于新生代。同样启用该收集器(-XX:+UseParallelGC),新生代采用复制算法,老年代采用标记-整理算法。与ParNew收集器不同的是更关注系统吞吐量,支持GC自适应调节策略

Parallel Old -- 老年代多线程(并行)收集器;只作用于老年代,采用标记-整理算法。它是Parallel Scavenge收集器的老年代版本,通常配置-XX:+UseParallelOldGC新生代使用ParallelGC收集器、老年代使用ParallelOld收集器

CMS收集器

CMS(Concurrent Mark Sweep)收集器是一种以获取最短路径为目的的回收器,并行收集,基于标记-清除算法实现。

主要通过在不同的阶段标记对应引用关系,当发生GC时,虚拟机能以最快的方式判断对象是否存活。

G1收集器

JDK1.7新增,取代CMS

特点

分代垃圾回收

分区算法,不要求新生代、老年代空间都连续

并行、并发,支持GC线程和用户线程同时进行以提高效率

空间整理:回收过程中会进行对象适当位置调整,减少空间碎片

可预见性:可选取部分区域进行回收,缩小回收范围,减少全局停顿

截图

Java内置监控工具:jconsole(终端输入命令即可打开)

联系

QQ交流群:671017003 欢迎各位前辈或萌新入驻

java监控gc线程_Java应用性能监控系统,使用JMX实现,实现了类加载监控、内存监控、线程监控、GC监控...相关推荐

  1. linux线程一直在增加,在.net core中遇到的奇怪问题:内存与线程数一直增长

    一个 asp.net core 站点,之前运行在 linux 服务器上,运行一段时间后有时站点会挂掉,有一次的症状是 asp.net core站点在高并发下出现的"EMFILE too ma ...

  2. java -jar 未响应_Java 方法性能监控和统计工具 MyPerf4J

    一个针对高并发.低延迟应用设计的高性能 Java 性能监控和统计工具. 特性 高性能: 单线程支持每秒 1000 万次 响应时间的记录,每次记录只花费 73 纳秒 无侵入: 采用 JavaAgent ...

  3. java 静态变量 存储_Java学习笔记9---类静态成员变量的存储位置及JVM的内存划分...

    笔记8提到了类静态成员变量的访问方式,但静态成员变量存储在哪里呢?在网上查阅不少资料,发现好多内容都是过时的了,其中主流观点是静态成员变量存放在方法区.JDK8之前,静态成员变量确实存放在方法区:但J ...

  4. java 点餐界面_Java小项目点餐系统(二)之服务端 | 学步园

    服务端详解: 服务端的主要功能就是无限监听一个端口号,对客户端发来的连接请求给予回应,然后开辟新线程处理客户端.界面做的比较简单就是显示在线的用户,分为商家和学生. 一.监听客户端的socket连接请 ...

  5. java slf4j日志级别_java - 在slf4j中设置运行时消息的日志级别 - 堆栈内存溢出

    ===============>>#1 票数:41 已采纳 使用slf4j无法做到这slf4j . 我想,缺少这个功能的原因是,几乎不可能为slf4j构建一个Level类型,它可以有效地映 ...

  6. java怎么获取当前日期_JAVA中获取当前系统时间

    一. 获取当前系统时间和日期并格式化输出: import java.util.Date; import java.text.SimpleDateFormat; public class NowStri ...

  7. java 当前时间格式_JAVA中获取当前系统时间及格式转换

    一. 获取当前系统时间和日期并格式化输出: import java.util.Date; import java.text.SimpleDateFormat; public class NowStri ...

  8. java 获取组件大小_java - 如何初始化取决于组件大小的图像抓取? - 堆栈内存溢出...

    如果我正确理解问题,那么您的方法会有些落后. 与其让ImageNavigator告诉ZoomedImage绘制哪个子图像,不如让ZoomedImage在绘制时询问ImageNavigator(通过重写 ...

  9. java商城源码_java 多商户商城系统源码分享

    三勾商城多商户是开发友好的微信小程序商城,框架支持SAAS,支持发布 iOS + Android + 公众号 + H5 + 各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)等多个平台,不可多得 ...

  10. java 源码 股票_java+实时股票报价系统源代码+NeatBeans java的股票系统 - 下载 - 搜珍网...

    实时股票报价系统\.classpath 实时股票报价系统\.project 实时股票报价系统\bin\lab_06\MyUtil.class 实时股票报价系统\bin\lab_06\Stock.cla ...

最新文章

  1. linux fcntl注销信号,fcntl · Linux C API 参考手册 · 看云
  2. postgis学习笔记
  3. yii2 mysql like_Yii2实现跨mysql数据库关联查询排序功能
  4. OpenCV学习笔记(十一)(十二)(十三)(十四)(十五)
  5. 1803无法升级到2004_微软向win10 1803以后版本推送新的Edge浏览器更新 安装后不再支持直接卸载...
  6. defer func(参数){}
  7. 掌握jQuery插件开发
  8. 漫话:如何给女朋友解释鸿蒙OS是怎样实现跨平台的?
  9. 2021年五一杯数学建模A题(疫苗生产调度问题)详细分析
  10. Dubbo的设计理念原来就藏在这三张图中
  11. 【es】ELASTICSEARCH之自定义JAVA代码的安全策略管理
  12. python内存池_python内存监控工具memory_profiler和guppy的用法详解
  13. Bailian4107 19岁生日礼物-Birthday Gift【进制】
  14. 蓝桥杯2019真题-完全二叉树的权值
  15. Python 用下划线作为变量前缀和后缀指定特殊变量
  16. 单片机的直流电机调速控制系统
  17. 点成分享 | 探索生物学中的电泳
  18. 小辩《降薪求职,到底该不该?》
  19. 面对众多的选择,我选择什么
  20. 视频flv转mp4最快的几种方法(就是不用格式工厂)

热门文章

  1. html5张图片响应式自动轮播代码,利用jQuery实现响应式Banner图片轮播代码
  2. c语言实现16位定点数乘法,c语言 fixed-point 定点数 运算
  3. java事件监听机制 概述
  4. java构造器_Java入门第十三课:“如何使用构造器初始化对象?”
  5. 在Windows Server 2012R2离线安装.net framework3.5
  6. 无锁循环缓冲区的实现c语言,C++ 无锁环形缓冲区实现
  7. android 圆角图片 imageview,【android 图片圆角设定】CustomImageView简单一览
  8. 多时相地图瓦片简单设想
  9. Navicat远程连接服务器Mysql
  10. 【CART与GBDT】