6、JVM-JVM调优工具与实战

前置启动程序

事先启动一个web应用程序,用jps查看其进程id,接着用各种jdk自带命令优化应用

Jmap

此命令可以用来查看内存信息,实例个数以及占用内存大小

jmap -histo 14660 #查看历史生成的实例

jmap -histo:live 14660 #查看当前存活的实例,执行过程中可能会触发一次full gc

 打开log.txt,文件内容如下:

  • num:序号
  • instances:实例数量
  • bytes:占用空间大小
  • class name:类名称,[C is a char[],[S is a short[],[I is a int[],[B is a byte[],[[I is a int[][]

堆信息

堆内存dump

jmap -dump:format=b,file=eureka.hprof 14660

 

也可以设置内存溢出自动导出dump文件(内存很大的时候,可能会导不出来)

  1. -XX:+HeapDumpOnOutOfMemoryError
  2. -XX:HeapDumpPath=./   (路径)

可以用jvisualvm命令工具导入该dump文件分析

Jstack

用jstack加进程id查找死锁,见如下示例

"Thread-1" 线程名

prio=5 优先级=5

tid=0x000000001fa9e000 线程id

nid=0x2d64 线程对应的本地线程标识nid

java.lang.Thread.State: BLOCKED 线程状态

还可以用jvisualvm自动检测死锁

jstack找出占用cpu最高的线程堆栈信息 

1,使用命令top -p ,显示你的java进程的内存情况,pid是你的java进程号,比如19663

0

2,按H,获取每个线程的内存情况

0

3,找到内存和cpu占用最高的线程tid,比如19664

4,转为十六进制得到 0x4cd0,此为线程id的十六进制表示

5,执行 jstack 19663|grep -A 10 4cd0,得到线程堆栈信息中 4cd0 这个线程所在行的后面10行,从堆栈中可以发现导致cpu飙高的调用方法

0

6,查看对应的堆栈信息找出可能存在问题的代码

Jinfo

查看正在运行的Java应用程序的扩展参数

查看jvm的参数

0

查看java系统参数

0

Jstat

jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:

jstat [-命令选项] [vmid] [间隔时间(毫秒)] [查询次数]

注意:使用的jdk版本是jdk8

垃圾回收统计

jstat -gc pid 最常用,可以评估程序内存使用及GC压力整体情况

0

  • S0C:第一个幸存区的大小,单位KB
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • MC:方法区大小(元空间)
  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间,单位s
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间,单位s
  • GCT:垃圾回收消耗总时间,单位s

堆内存统计

0

  • NGCMN:新生代最小容量
  • NGCMX:新生代最大容量
  • NGC:当前新生代容量
  • S0C:第一个幸存区大小
  • S1C:第二个幸存区的大小
  • EC:伊甸园区的大小
  • OGCMN:老年代最小容量
  • OGCMX:老年代最大容量
  • OGC:当前老年代大小
  • OC:当前老年代大小
  • MCMN:最小元数据容量
  • MCMX:最大元数据容量
  • MC:当前元数据空间大小
  • CCSMN:最小压缩类空间大小
  • CCSMX:最大压缩类空间大小
  • CCSC:当前压缩类空间大小
  • YGC:年轻代gc次数
  • FGC:老年代GC次数

新生代垃圾回收统计

0

  • S0C:第一个幸存区的大小
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • TT:对象在新生代存活的次数
  • MTT:对象在新生代存活的最大次数
  • DSS:期望的幸存区大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间

新生代内存统计

0

  • NGCMN:新生代最小容量
  • NGCMX:新生代最大容量
  • NGC:当前新生代容量
  • S0CMX:最大幸存1区大小
  • S0C:当前幸存1区大小
  • S1CMX:最大幸存2区大小
  • S1C:当前幸存2区大小
  • ECMX:最大伊甸园区大小
  • EC:当前伊甸园区大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代回收次数

老年代垃圾回收统计

0

  • MC:方法区大小
  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

老年代内存统计

0

  • OGCMN:老年代最小容量
  • OGCMX:老年代最大容量
  • OGC:当前老年代大小
  • OC:老年代大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

元数据空间统计

0

  • MCMN:最小元数据容量
  • MCMX:最大元数据容量
  • MC:当前元数据空间大小
  • CCSMN:最小压缩类空间大小
  • CCSMX:最大压缩类空间大小
  • CCSC:当前压缩类空间大小
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

0

  • S0:幸存1区当前使用比例
  • S1:幸存2区当前使用比例
  • E:伊甸园区使用比例
  • O:老年代使用比例
  • M:元数据区使用比例
  • CCS:压缩使用比例
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

JVM运行情况预估

用 jstat gc -pid 命令可以计算出如下一些关键数据,有了这些数据就可以采用之前介绍过的优化思路,先给自己的系统设置一些初始性的JVM参数,比如堆内存大小,年轻代大小,Eden和Survivor的比例,老年代的大小,大对象的阈值,大龄对象进入老年代的阈值等。

年轻代对象增长的速率

可以执行命令 jstat -gc pid 1000 10 (每隔1秒执行1次命令,共执行10次),通过观察EU(eden区的使用)来估算每秒eden大概新增多少对象,如果系统负载不高,可以把频率1秒换成1分钟,甚至10分钟来观察整体情况。注意,一般系统可能有高峰期和日常期,所以需要在不同的时间分别估算不同情况下对象增长速率。

Young GC的触发频率和每次耗时

知道年轻代对象增长速率我们就能推根据eden区的大小推算出Young GC大概多久触发一次,Young GC的平均耗时可以通过 YGCT/YGC 公式算出,根据结果我们大概就能知道系统大概多久会因为Young GC的执行而卡顿多久。

每次Young GC后有多少对象存活和进入老年代

这个因为之前已经大概知道Young GC的频率,假设是每5分钟一次,那么可以执行命令 jstat -gc pid 300000 10 ,观察每次结果eden,survivor和老年代使用的变化情况,在每次gc后eden区使用一般会大幅减少,survivor和老年代都有可能增长,这些增长的对象就是每次Young GC后存活的对象,同时还可以看出每次Young GC后进去老年代大概多少对象,从而可以推算出老年代对象增长速率。

Full GC的触发频率和每次耗时

知道了老年代对象的增长速率就可以推算出Full GC的触发频率了,Full GC的每次耗时可以用公式 FGCT/FGC 计算得出。

优化思路其实简单来说就是尽量让每次Young GC后的存活对象小于Survivor区域的50%,都留存在年轻代里。尽量别让对象进入老年代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。

内存泄露到底是怎么回事

再给大家讲一种情况,一般电商架构可能会使用多级缓存架构,就是redis加上JVM级缓存,大多数同学可能为了图方便对于JVM级缓存就简单使用一个hashmap,于是不断往里面放缓存数据,但是很少考虑这个map的容量问题,结果这个缓存map越来越大,一直占用着老年代的很多空间,时间长了就会导致full gc非常频繁,这就是一种内存泄漏,对于一些老旧数据没有及时清理导致一直占用着宝贵的内存资源,时间长了除了导致full gc,还有可能导致OOM。

这种情况完全可以考虑采用一些成熟的JVM级缓存框架来解决,比如ehcache等自带一些LRU数据淘汰算法的框架来作为JVM级的缓存。

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

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

相关文章

SQL12 获取每个部门中当前员工薪水最高的相关信息

题目:获取每个部门中当前员工薪水最高的相关信息 注意了,这道题目,分组函数只能查出来:每个部门的最高薪水,group by dept_no ,根据部门分组,绝对不能group by dept_no,emp_no,不能…

云正在使 IT 受益,但对业务却没有好处

云具有巨大的商业价值!这是云提供商及其盟友在每次云计算会议上高喊的战斗口号。 您永远不会听到我说“云”始终是正确的解决方案,或者就此而言,是错误的解决方案。 在作为云专家 20 多年的时间里,从来没有盲目追随云计算先驱或…

Educational Codeforces Round 164 (Rated for Div. 2)

D. Colored Balls 题意:给你n个颜色不同的小球,以及每种颜色小球的数量,让你求 种集合分割方案的价值和 我们考虑一个集合的贡献,如果最大值大于sum的一半,那么值就是max,反之值就是(sum1)/2 那么我们可…

Docker Desktop修改镜像存储路径 Docker Desktop Start ... 卡死

1、CMD执行wsl -l -v --all 2、Clean / Purge data 3、导出wsl子系统镜像: wsl --export docker-desktop D:\docker\wsl\distro\docker-desktop.tar wsl --export docker-desktop-data D:\docker\wsl\data\docker-desktop-data.tar4、删除现有的wsl子系统: wsl -…

快速寻找可以构建出网通信隧道的计算机

点击星标,即时接收最新推文 本文选自《内网安全攻防:红队之路》 扫描二维码五折购书 为加强内网的安全防范,安全管理员往往会限制内网计算机访问互联网,当然不同机构的限制策略是不一样的,有的完全阻断了内网计算机访问…

【Linux】进程的优先级及linux下进程的调度于切换

目录 ​编辑 1.优先级是什么 2.linux中的优先级是怎么实现的 ps -la 命令查看当前用户启动的进程​编辑 linux下调整优先级: ①先top一下 ②点击r ③需要输入进程的pid ④回车 ​编辑 ⑤输入想将优秀级修改的值: linux进程优先级范围为什么必须是【60,9…

自编译支持CUDA硬解的OPENCV和FFMPEG

1 整体思路 查阅opencv的官方文档,可看到有个cudacodec扩展,用他可方便的进行编解码。唯一麻烦的是需要自行编译opencv。 同时,为了考虑后续方便,顺手编译了FFMPEG,并将其与OPENCV绑定。 在之前的博文“鲲鹏主机昇腾A…

osg场景图的数据结构

1、Scene Graph场景图 场景图是一种描述三维场景的数据结构:它是一个有向无循环图。 OSG中不仅定义了场景图的数据结构,还提供了对这种图数据结构的各种访问方式,或者说是管理方法,如渲染。 2、常见节点 备注:Tranform变换的是模…

小车项目介绍

STM32智能小车基于STM32F103C8T6进行开发 该项目具有OLED,USART串口,ADC测量电压,陀螺仪,超声波测距模块,红外循迹模块,蓝牙模块,按键,电机驱动,电机,舵机,电源等功能 功能详细介绍: OLED模块 使用:OLED显示屏模块 0.96寸 IIC/SPI 选择原因:价格较低、使用方便…

如何在jmeter中把响应中的数据提取出来并引用

jmeter做接口测试过程中,经常遇到请求需要用到token的时候,我们可以把返回token的接口用后置处理器提取出来,但是在这种情况下,只能适用于当前的线程组,其他线程组无法引用到提取的token变量值,所以必须要生…

如何用好PMP项目管理知识

PMP(Project Management Professional,项目管理专业人士)是由国际项目管理协会(PMI)颁发的全球最高级别的项目管理认证,认证需要通过严格的考试,并具备相应的工作经验和教育背景。 作为一名咨询师,我们经常…

vscode和pycharm等idea编写protobuf文件格式化

想在pycharm或者goland等idea中开发protobuf文件的话,可以安装一个插件:protocol-buffers 安装之后,proto文件就会支持高亮和格式化了。 如果是vscode想要编写proto文件,可以安装另外一个插件:vscode-proto3 安装后&a…

C++修炼之路之list模拟实现--C++中的双向循环链表

目录 引言 一:STL源代码中关于list的成员变量的介绍 二:模拟实现list 1.基本结构 2.普通迭代器 const迭代器的结合 3.构造拷贝构造析构赋值重载 清空 4.inserterase头尾插入删除 5.打印不同数据类型的数据《使用模板加容器来完成》 三&#xf…

AGI趋势/创业的从业者

红杉这两年分享了好多AI文章,收录了多篇关于GenAI的观点和文章,涉及GenAI的未来、趋势、应用和挑战等话题。 比如: 2024 年的人工智能:从大爆炸到原始汤 下一个十亿开发者 生成式人工智能的第二幕 AI 的 $200B 问题 将生成式…

2024 MathorCupC题完整解题及成品论文!

C 题 物流网络分拣中心货量预测及人员排班 电商物流网络在订单履约中由多个环节组成,图 1 是一个简化的物流 网络示意图。其中,分拣中心作为网络的中间环节,需要将包裹按照不同 流向进行分拣并发往下一个场地,最终使包裹到达消费者手中。分拣中心 管理效率的提升,对整体网络的…

华为ensp中nat server 公网访问内网服务器

作者主页:点击! ENSP专栏:点击! 创作时间:2024年4月15日17点30分 NAT服务器是一种在网络边界设备上配置的服务,它允许外部网络的用户访问内部网络中的服务或主机,同时隐藏了内部网络的真实IP地…

快速探索随机树-RRT

文章目录 简介原理算法运动规划的变体和改进简介 快速探索随机树(RRT)是一种算法,旨在通过随机构建空间填充树来有效搜索非凸高维空间。该树是从搜索空间随机抽取的样本中逐步构建的,并且本质上偏向于向问题的大型未搜索区域生长。RRT 由 Steven M. LaValle 和 James J. K…

冯喜运:4.16市场洞察:中东风暴搅动汇市,现货黄金原油走势分析

【黄金消息面分析 】周一(4月15日),欧洲时段黄金价格已经从高点回落,目前交投于2351.52美元/盎司,稍早曾短暂攀至2372美元,未能重现上周收盘时触及的2431美元高位。定于周一晚些时候公布的美国3月零售销售数据也可能对美元汇率产生…

PgSQL之WITH Queries/Statement

PostgreSQL WITH 子句 在 PostgreSQL 中,WITH 子句提供了一种编写辅助语句的方法,以便在更大的查询中使用。 WITH 子句有助于将复杂的大型查询分解为更简单的表单,便于阅读。这些语句通常称为通用表表达式(Common Table Express…

1260. 二维网格迁移

1260. 二维网格迁移 原题链接:完成情况:解题思路:参考代码:错误经验吸取 原题链接: 1260. 二维网格迁移 https://leetcode.cn/problems/shift-2d-grid/description/ 完成情况: 解题思路: 这…