当前位置: 首页 > news >正文

【JVM】内存分析工具JConsole/Visual VM

1 缘起

日常补充JVM调优,调优实践前需要学习一些理论做支撑,
JVM调优三步:理论=>GC分析=>JVM调优,
我们会有一些玩笑话说,做了这么久Java开发,做过JVM调优吗?
做过,面试时。当然,不同职业阶段有不同的需求,面试中有面试的需求,工作中有工作需求,
面试时是必背需求,工作中是可选需求,我们维护稳定的系统时,自然不需要JVM调优,
当我们需要为新业务构建新系统或者业务发展调整系统时,为保证系统稳定运行,就需要JVM参数配置以及调优了。

调优方案,是依据当前系统资源以及业务实际情况最终确定的:减少Full GC频率。
(1)硬件资源尚有可用,可直接增加年轻代和老年代堆内存,减少Full GC频率;
(2)硬件资源不足(原因不论),调整年轻代内存分配,减少Full GC频率,依据当前业务场景,计算每次请求占用的内存,做限流处理;
(3)硬件资源不足,业务逻辑中有冗余数据生成,去除冗余数据或者调整业务需求,如减少单次数据生成量,减少Full GC频率。
请添加图片描述

2 一些理论基础

JVM自带内存回收,设计者将JVM运行时数据区的堆进一步进行划分,
一方面可以高效使用内存,另一方面灵活配置内存,适应不同的场景。
JDK8中的JVM运行时数据区堆分为老年代和年轻代,结构如下图所示:
所以我们调整的堆大小就是新生代的Eden区和老年代,
不同区的内存回收有不同的术语,如Minor GC、Major GC和Full GC。

  • Minor GC:针对年轻代Eden区内存回收。当新生成的对象在Eden区无法正常分配时,会触发Minor GC,并将Eden区仍存活的对象拷贝到Survivor区,当From Survivor区达到年龄阈值的对象超过From或To Survivor空间一半时,会将这部分对象分配到老年代。
  • Major GC:针对老年代内存回收。当Eden区存活的对象进入老年代或者Eden区无法分配的对象直接进入老年代,而老年代没有足够内存分配,发生Major GC。
  • Full GC:针对年轻代和老年代内存回收。当老年代空间不足(直接进入老年代的新建对象)、YGC对象晋升失败(Survivor对象达到年龄设定值,进入老年代,老年代没有足够空间分配)、YGC晋升到老年代对象平均总大小大于老年代空闲空间时发生Full GC。

Full GC对整个JVM运行时数据区影响最大,不同的垃圾回收器有不同表现,如Serial垃圾回收器会发生STW(Stop The World),导致内存回收期间服务不可用,服务处于离线状态。

  • 最终结论:最大限度减少Full GC频率,保证服务在线时间。

在这里插入图片描述

2 JVM运行时数据区:堆 观测工具

有了上面的理论基础,我们可以正确阅读【堆】运行状态以及当前JVM运行状态。
查看当前服务JVM运行时数据区堆的运行状况有多种方式,如查看GC日志、JConsole、Visula VM等工具。
本文就介绍如何使用JConsole和Visual VM查看JVM运行时数据区堆实时状态。

2.1 JConsole

JConsole是JDK提供的原生工具,安装JDK后,通过命令行即可开启JConsole,以Windows为例,
控制台输入:jconsole

在这里插入图片描述
默认的JConsole用户界面如下,有两种连接Java进程的方式,
直接连接本地Java进程或者通过IP和Port连接远程Java进程,本文演示连接本地Java进程。
在这里插入图片描述

2.1.1 老年代

连接本地Java进程后,菜单栏有概览、内存、线程、类等,我们分析JVM运行时数据区堆的使用情况,
因此查看内存菜单下信息。
通过切换图标标签,可查看不同分代的状态,如老年代。
通过老年代GC频率可以直观看出系统的稳定性,老年代GC频率高,系统不稳定性高,老年代GC频率与系统稳定性反比关系或者老年代GC频率与系统不稳定性正比关系。
这里查看老年代内存回收情况,老年代GC即曲线下降时发生,
通过老年代GC我们可以推测此时发生了Major GC或者Full GC,此时JVM运行时数据区堆老年代已无足够内存供系统使用,
老年代GC曲线拐点出现频次即发生Major GC或Full GC的频次,如果下图的波峰在单位时间(分钟或小时)内出现多次,说明系统稳定性夏下降了,需要关注系统运行情况,并进一步排查什么原因引发Major GC或Full GC的。

在这里插入图片描述

2.1.2 年轻代:Eden区

年轻代Eden区GC曲线如下图所示,
通过Eden区内存回收情况可以了解当前年轻代健康状况,
单位时间内Eden区回收次数较多(依实际情况而定),说明当前系统Eden区分配较小或者当前业务系统的对象朝生夕死的大对象较多,需要即时调整年轻代Eden区大小,减少Minor GC频率。
下面模拟的情况就是Eden区分配的内存较小,Minor GC频率高达:7次/分钟,这里配置的年轻代10MB,
为验证使用,年轻代内存分配不足,需要增加年轻代内存。

在这里插入图片描述

2.1.3 Survivor区

新生代Eden区发生GC时,最先受到影响的时Survivor区,
当Eden区内存回收时,即Mnior GC,会将存活的对象复制到Survivor From(S0)区,对象年龄+1,
再次发生Minor GC时,会将Eden区和Survivor From区区存活的对象复制到Survivor To(S1)区,
S0和S1区在发生Minor GC时依次轮转,保证MinorGC后存活的对象分配连续的内存,避免内存碎片化,
当Survivor From/To区对象达到预设的年龄或者对象超过Survivor From/To区域一半时,将这部分对象会晋升到老年代。
因此,Survivor区GC频率从侧面说明了进入老年代对象的频率,
频率越高,说明年轻代分配的内存不足或者当前业务系统对象生成逻辑存在需要优化的情况。

在这里插入图片描述

2.2 Visual VM

Visual VM是另一个GC可视化工具,原先是JDK的内置工具,但是从谋个JDK版本之后,Visual VM已从JDK中移除,需要单独下载使用。

在这里插入图片描述
Visual VM地址:https://visualvm.github.io

在这里插入图片描述

下载后,可执行文件:

在这里插入图片描述
Visual VM如何观测JVM的GC情况呢?当然有工具,Visual GC插件即可观测。
(1)安装Visula GC插件
在这里插入图片描述

在这里插入图片描述

(2)使用Visual GC插件
安装Visual GC插件后重启Visual GC,检测Java进程,通过Visual GC菜单栏即可观测当前Java进程的GC情况,
实际采集的结果如下图所示,Visual GC插件将JVM运行时数据区堆部分整合在一起方便查看。
这里分析与上面JConsole一致,不赘述。
如果想要更好的GC观测体验,推荐Visual GC。

在这里插入图片描述

3 小结

(1)Minor GC发生条件:Eden区被对象占满时发生,回收Eden区内存,将存活的对象复制到Survivor From(S0)区,再次发生Minor GC时,将存活的对象以及S0的对象复制到S1区,如此往复,S0与S1轮转,当S0/S1区对象满足(占用50%或者对象达到年龄阈值时)晋升到老年代:
(1.1)Eden区存活的对象大于S0或S1区50%时,直接进入老年代,不进入S0或S1区;
(1.2)S0/S1区的存活的对象超过50%,对象晋升到老年代;
(1.3)S0/S1区存活的对象年龄超过指定阈值(默认15)时,对象晋升到老年代。
(2)Major GC发生条件:老年代内存被占满时,回收老年代内存。
(3)Full GC发生条件:老年代空间不足分配新对象、YGC担保失败、YGC晋升到老年代对象平均大小大于老年代空闲空间或者显式调用System.gc,回收年轻到和老年代内存。
调优方案,是依据当前系统资源以及业务实际情况最终确定的:减少Full GC频率。
(1)硬件资源尚有可用,可直接增加年轻代和老年代堆内存,减少Full GC频率;
(2)硬件资源不足(原因不论),调整年轻代内存分配,减少Full GC频率,依据当前业务场景,计算每次请求占用的内存,做限流处理;
(3)硬件资源不足,业务逻辑中有冗余数据生成,去除冗余数据或者调整业务需求,如减少单次数据生成量,减少Full GC频率。

相关文章:

【JVM】内存分析工具JConsole/Visual VM

1 缘起 日常补充JVM调优,调优实践前需要学习一些理论做支撑, JVM调优三步:理论>GC分析>JVM调优, 我们会有一些玩笑话说,做了这么久Java开发,做过JVM调优吗? 做过,面试时。当然…...

一静 、二平 、三忍 、四让、五淡

一静 、二平 、三忍 、四让、五淡。 作者:儒风君 来源:儒风大家(ID: rufengdajia) 古人为人、处事、修身,都有独特的章法。 一静、二平、三忍、四让、五淡。 说透中国人的大智慧。 1 静 《道德经》里讲:“清静为天下正。”…...

js 深入理解函数(一):函数的本质

目录 概述1. 箭头函数2. 函数名 :指向函数的指针3. 理解参数3.1 arguments 对象的作用3.2 arguments 的注意点3.3 箭头函数中的参数 4. 没有重载5. 默认参数值5.1 ES 6 支持显示定义默认参数5.2 传 undefined 等于没有传值5.3 arguments 不反映参数默认值5.4 默认值…...

MySql表结构设计

创建 create table 表名(字段1 字段类型 [约束] [comment 字段1注释],...) [comment 表注释];约束是作用于表中字段上的规则,用于限制存储在表中的数据。它的目的是保证数据库中数据的正确性、有效性和完整性。 约束描述关键字非空约束限制该字段不能为nullnot nu…...

java:pdfbox 3.0 去除扫描版PDF中文本水印

官网下载 https://pdfbox.apache.org/download.html下载 pdfbox-app-3.0.3.jar cd D:\pdfbox 运行 java -jar pdfbox-app-3.0.3.jar java -jar pdfbox-app-3.0.3.jar Usage: pdfbox [COMMAND] [OPTIONS] Commands:debug Analyzes and inspects the internal structu…...

python知识点100篇系列(17)-替换requests的python库httpx

Requests 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,使用Requests可以轻而易举的完成浏览器可有的任何操作。 但是在python3.6之后,出现了一个requests的替代选项; httpx httpx是Python新一代的网络请求库…...

python 实现graph list图列算法

graph list图列算法介绍 图列(Graph List)算法通常指的是在图的表示中,使用列表(List)或更具体地说,邻接表(Adjacency List)来表示图的一种算法。邻接表是图的一种常见表示方法&…...

LFU算法 初始频率 动态频率

LFU(Least Frequently Used)算法是一种缓存淘汰策略,其核心思想是根据数据的访问频率来决定淘汰哪些数据。具体来说,     LFU算法认为如果一个数据在过去一段时间内被访问的次数很少,那么它在未来被再次访问的概率也…...

Spring Boot 进阶-详解SpringBoot的复杂数据校验规则

在之前的文章中,我们介绍了SpringBoot整合JSR-303规则来完成数据校验操作。接下来我们来聊一聊关于数据校验的具体用法。 之前的文章中举过一个简单的例子通过学生信息提交的例子来介绍了关于数据校验如何去做。那么接下来这篇文章,我们就来看看对于一些复杂的数据校验如何完…...

wsl环境下安装Ubuntu,并下载MySQL5.7

安装操作需root权限,切换root用户有两种方式: 1-通过 sudo su - ,切换到root用户(登录后长期有效)。 2-在每一个命令前加上sudo,临时提升权限(仅对一条命令有效)。 1、下载apt仓库…...

倪师学习笔记-天纪-01

一、概要 介绍课程内容,介绍部分概念 二、具体内容 1、天纪内容 天机道:看象,使用斗数等工具人间道:看卦,使用易经地脉道:看风水地理 2、神 神与形对应,形是神的实例,神是形的…...

深入理解缓存穿透、缓存击穿和缓存雪崩

在现代分布式系统中,缓存是提升系统性能和减轻数据库负载的重要组件。然而,在实际应用中,我们可能会遇到一些缓存问题,如缓存穿透、缓存击穿和缓存雪崩。本文将详细探讨这三种缓存问题的原理、影响以及解决方案。 一,…...

【玩转动态规划专题】70. 爬楼梯【简单】

【玩转动态规划专题】70. 爬楼梯【简单】 1、力扣链接 https://leetcode.cn/problems/climbing-stairs/description/ 2、题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1&…...

前端开发设计模式——组合模式

目录 一、组合模式的定义和特点 1.定义 2.特点: 二、组合模式的实现方式 1.定义抽象组件类 2.创建叶节点类 3.创建组合类: 三、组合模式的应用场景 1.界面布局管理 2.菜单系统构建 3.组件库开发 四、组合模式的优点 1.简化客户端代码 2.增…...

初探OceanBase 4.x单机环境下如何进行主备架构搭建

本文来自OceanBase 用户的体验分享 (以下简称 OB),已经开源了3年左右,其间从3.x版本演进至4.x版本,发生了许多变化。对一个DBer而言,最为关切的是如何高效运用OB,以及是否能实现如同应用MySQL般…...

python 实现Edmonds-Karp算法

Edmonds-Karp算法介绍 Edmonds-Karp算法是一种用于解决最大流问题的算法,在计算机科学中广泛应用。以下是关于Edmonds-Karp算法的详细解释: 算法概述 Edmonds-Karp算法是基于Ford-Fulkerson方法的改进,它通过广度优先搜索(BFS&…...

【牛客刷题实战】BC120 争夺前五名

大家好,我是小卡皮巴拉 文章目录 目录 牛客题目: BC120 争夺前五名 题目描述 输入描述: 输出描述: 示例1 示例2 解题思路: 具体思路: 题目要点: 完整代码: 兄弟们共…...

WMS 智慧仓储管理系统的可视化管理_SunWMS

【大家好,我是唐Sun,唐Sun的唐,唐Sun的Sun。一站式数智工厂解决方案服务商】 WMS 智慧仓储管理系统的可视化管理主要表现在以下几个方面: 首先是库存可视化。通过系统,仓库管理人员能够以直观的图表、图形等形式清晰地…...

动态代理代码示例

理解动态代理 动态代理的核心在于代理对象的创建和方法调用是在运行时动态发生的,而不是在编译时就已经确定的性能监控、事务管理、日志记录通常需要使用代理对象对目标对象的功能进行增强为什么JDK动态代理只能代理有接口的类? 因为Proxy.newProxyIns…...

SpringBoot+Activiti7工作流使用进阶实例-高亮显示BPMN流程图( SpringBoot+Activiti+mybatis+shiro实现)

文章目录 说明绘制流程图排他网关设置任务节点设置创建工程修改 pom.xml 文件准备数据库的表和测试数据修改 application.yml 文件配置静态资源Shiro 相关配置ShiroConfiguration.javaMyShiroRealm.java流程控制器添加静态的资源和模板页面运行结果截图源码地址说明 使用 Spri…...

C#使用Lazy<T>提高性能

以下是一些适合使用Lazy<T>的场景&#xff1a; 单例模式 在实现单例模式时&#xff0c;Lazy<T>是非常有用的。如前面提到的示例&#xff0c;它可以确保单例对象在首次被访问时才进行创建&#xff0c;同时在多线程环境下也能保证正确的行为。这种方式比传统的双重检…...

创建读取比特币1P类型地址

创建读取比特币1P类型地址 比特币的地址类型有多种&#xff0c;其中 P2TR&#xff08;Pay-to-Taproot&#xff09;地址是基于最近的升级&#xff08;Taproot&#xff09;引入的一个新类型。本文将介绍如何创建和读取比特币的 1P 类型地址&#xff0c;主要通过 JavaScript 和相…...

从零开始Hadoop集群环境搭建

目录 1. Centos7.5硬件配置1.1 创建虚拟机1.2 虚拟机系统设置 2. IP地址和主机名称配置3. 软件配置3.1 安装 epel-release3.2 卸载虚拟机自带的JDK3.3 克隆虚拟机3.4 修改克隆虚拟机的IP3.5 JDK安装3.6 Hadoop安装 4. Hadoop目录结构 1. Centos7.5硬件配置 1.1 创建虚拟机 1.2…...

Copley耐环境伺服驱动器 极端环境下高精度控制解决方案

全球工业环境的日益复杂多变&#xff0c;对伺服驱动器的要求不再局限于基本的性能参数&#xff0c;而是在极端环境下的稳定性与可靠性。Copley耐环境伺服驱动器以卓越的性能和出色的环境适应性&#xff0c;为工业自动化领域的高精度控制提供了可靠的解决方案。 一、多样化的产…...

前端的全栈混合之路Meteor篇:分布式数据协议DDP深度剖析

本文属于进阶篇&#xff0c;并不是太适合新人阅读&#xff0c;但纯粹的学习还是可以的&#xff0c;因为后续会实现很多个ddp的版本用于web端、nodejs端、安卓端和ios端&#xff0c;提前预习和复习下。ddp协议是一个C/S架构的协议&#xff0c;但是客户端也同时可以是服务端。 什…...

基于Zynq SDIO WiFi移植一(支持2.4/5G)

基于SDIO接口的WIFI&#xff0c;在应用上&#xff0c;功耗低于USB接口&#xff0c;且无须USB Device支持&#xff0c;满足某些应用场景 1 硬件连接 2 Vivado工程配置 3 驱动编译 3.1 KERNRL CONFIG (build ENV) 修改 export KERNELPATH<path of kernel header>export T…...

数据结构与算法篇(刷题篇 - 链表)

目录 1. 反转链表&#xff08;简单&#xff09; 1.1. 题目描述 1.2. 解题思路 方法一&#xff1a;迭代&#xff08;推荐使用&#xff09; 方法二&#xff1a;递归&#xff08;扩展思路&#xff09; 方法三&#xff1a;使用栈解决 方法四&#xff1a;双链表求解 2. 链表内…...

TinyAgent: 从零开始构建最小化Agent系统

引言 随着大模型&#xff08;LLM&#xff09;的崛起&#xff0c;特别是ChatGPT等大模型的广泛应用&#xff0c;基于LLM的系统越来越受欢迎。然而&#xff0c;尽管大模型具备强大的生成能力和推理能力&#xff0c;它们在处理某些专有领域或实时问题时仍然存在局限性。因此&#…...

Android Studio New里面没有New Flutter Project

跟着Flutter中文网的配置教程&#xff0c;安装好了flutter,在Android studio里面也安装了dart和flutter的插件。重启后还是在FIle->New里面没有显示New Flutter Project。 反复卸载重装dart和flutter插件好几次&#xff0c;依然没有效果。 原来是没有把Android APK Suppor…...

linux信号 | 学习信号四步走 | 透析信号是如何被处理的?

前言&#xff1a;本节内容讲述linux信号的捕捉。 我们通过前面的学习&#xff0c; 已经学习了信号的概念&#xff0c; 信号的产生&#xff0c; 信号的保存。 只剩下信号的处理。 而信号的处理我们应该着重注意的是第三种处理方式——信号的捕捉。 也就是说&#xff0c; 这篇文章…...