二十分钟带你了解JVM性能调优与实战进阶

ZGC

诞生原因

Java生态非常强大,但还不够,有些场景仍处于劣势,而ZGC的出现可以让Java语言抢占其他语言的某些特定领域市场。比如

  • 谷歌主导的Android手机系统显示卡顿。
  • 证券交易市场,实时性要求非常高,目前主要是C++主导。
  • 大数据集群如HBase的性能。

特性

  • ZGC(The Z Garbage Collector)为JDK11推出一款低延迟的垃圾回收器。STW即停顿时间低于1ms,且不会随着堆的大小增加而增加。
  • 实现主要原理:全并发处理(仅对GC ROOTS进行遍历时会暂停)

  • 高版本JDK16之后支持16TB级别的堆;
  • 实现主要原理:Region分区管理、染色指针寻址

  • 应用程序吞吐量最多减少15%。
  • 实现主要原理:当生命周期很短的对象分配速率很高的时候,大量对象不会被进行标记收集,会产生大量浮动垃圾从而影响吞吐量,并且堆中可转移对象的空间就会越来越小。

  • 为未来的GC新特性奠定基础。
  • 实现主要原理:染色指针中未被使用预留的18 bits。

内存布局

ZGC采用堆空间分页模型的机制,堆空间分页模型也非常符合Linux Kernel2.6引入的标准大页(huge page)如4KB的处理方式。本质与G1一样,没有分代的概念,ZGC也采用基于Region的堆内存布局,不一样的是ZGC的Region具有动态性:动态创建销毁、动态容量大小。ZGC一共分为三种Region:

  • 小型Region(小页面):容量固定为 2MB,存放小于256KB的对象。
  • 中型Region(中页面):容量固定为 32MB,存放大于256KB小于4MB的对象。
  • 大型Region(大页面):容量为 2*N MB,可以动态变化,每个大Region中只会存放一个大对象,并且不会被重分配(即后文介绍的对象的复制),因为大对象的复制代价高昂。

指针着色技术(Color Pointers)

  • ZGC只支持64位的系统,也即是64位的指针。
  • ZGC在JDK11的ZGC来分析中低42位即2的42次方来表示使用中的堆空间,也即是可管理的内存,而在JDK更高版本有所变化。
  • ZGC借助几位高位来做GC相关的事情比如快速实现垃圾回收的并发标记、转移和重定位等。
  • 预留用来给未来的GC新特性预留的扩展点

一段C程序mapping.c看下ZGC的64位虚拟地址空间的指针着色技术展示

编译执行,三个地址一样,也即是同一个实地址映射到3个虚地址。

整体流程

概述

主要分为两步

  • 标记阶段(标记垃圾)
  • 转移阶段(对象复制或移动)

垃圾标记

垃圾标记算法采用可达性分析算法

  • Remapped
  • GC前所有内存都是Remapped,或者标记后如果还是Remapped则是垃圾。

  • M0,发生两次GC为例,M0是1次GC。
  • 前一次GC的标记阶段被标记过的活跃对象,但是上次GC未对对象进行转移。

  • M1,发生两次GC为例,M0是2次GC。
  • 本次垃圾回收中识别的活跃对象。

标记阶段,对象分配(Remapped)

  • 初始标记(标记根)
  • 并发标记(标记剩余)
  • 再标记(解决漏标)

标记结束后Remapped对象即为垃圾对象。而下次标记使用M1表示活跃。

ZGC转移

  • 如果是同一个页面则等同于标记整理。
  • 如果是不同页面等同于复制算法。

JVM调优概述

背景

  • 生产环境中的问题
  • 生产环境中的问题。
  • 生产环境发生了内存溢出该如何处理?
  • 生产环境应该给服务器分配多少内存合适?
  • 如何对垃圾回收器的性能进行调优?
  • 生产环境 CPU 负载飙高该如何处理?
  • 生产环境应该给应用分配多少线程合适?
  • 不加 log,如何确定请求是否执行了某一行代码?
  • 不加 log,如何实时查看某个方法的入参与返回值?

  • 为什么要调优
  • 防止出现 OOM
  • 解决 OOM
  • 减少 Full GC 出现的频率

  • 调优场景
  • Full GC 次数频繁。
  • GC 停顿时间过长(超过1秒)。
  • 应用出现OutOfMemory 等内存异常。
  • 系统吞吐量与响应性能不高或下降

  • 不同阶段的考虑
  • 上线前
  • 项目运行阶段
  • 线上出现 OOM

调优概述

  • 监控的依据
  • 运行日志
  • 异常堆栈
  • GC 日志
  • 线程快照
  • 堆转储快照

  • 调优的大方向
  • 合理地编写代码
  • 充分并合理的使用硬件资源
  • 合理地进行 JVM 调优

调优目标

JVM调优目标是使用较小的内存占用来获得较高的吞吐量或者较低的延迟,从这里也可以知道其重要指标有三个:

  • 内存占用:程序正常运行需要的内存大小。
  • 延迟:由于垃圾收集而引起的程序停顿时间。
  • 吞吐量:用户程序运行时间占用户程序和垃圾收集占用总时间的比值。

从上面我们也知道这三者如同分布式CAP理论一样不可完全兼得,对于一个Java程序同时保证内存占用小、延迟低、高吞吐量是不可能的;任何一个指标性能的提高,几乎都是以牺牲其他指标性能的损为代价的,不可兼得。程序的目标不同,调优时所考虑的方向也不同,因此需要结合实际场景,有明确的优化目标,找到性能瓶颈,对瓶颈有针对性的优化。

调优原则

  • 90%也即是大多数的Java应用不需要进行JVM优化。
  • 大多数导致GC问题的原因是代码层面的问题导致的(代码层面)。
  • 上线之前,应先考虑将机器的JVM参数设置到最优。
  • 减少创建对象的数量,减少使用全局变量和大对象(代码层面)。
  • 优先架构调优和代码调优,JVM优化是不得已的手段。
  • 分析GC情况优化代码比优化JVM参数更好。

调优步骤

  • 第 1 步:性能监控
  • GC 频繁
  • cpu load 过高(如top -hP 进程号;top -d 2 -c等)
  • OOM
  • 内存泄露
  • 死锁
  • 程序响应时间较长

  • 第 2 步:性能分析
  • 打印 GC 日志,通过 GCviewer 或者 gceasy来分析异常信息
  • 灵活运用命令行工具、jstack、jmap、jinfo 等
  • dump 出堆文件,使用内存分析工具分析文件
  • 使用阿里 Arthas、jconsole、JVisualVM 来实时查看 JVM 状态
  • jstack 查看堆栈信息

  • 第 3 步:性能调优
  • 适当增加内存,根据业务背景选择垃圾回收器
  • 优化代码,控制内存使用
  • 增加机器,分散节点压力
  • 合理设置线程池线程数量
  • 使用中间件提高程序效率,比如缓存、消息队列等

性能评价/测试指标

  • 停顿时间(或响应时间)
  • 提交请求和返回该请求的响应之间使用的时间,一般比较关注平均响应时间。
  • 数据库查询一条记录(有索引),十几毫秒。
  • 机械磁盘一次寻址定位。4毫秒
  • 从机械磁盘顺序读取 1M 数据。2毫秒
  • 从 SSD 磁盘顺序读取 1M 数据。0.3毫秒
  • 从内存读取 1M 数据。十几微妙
  • Java程序本地方法调用。几微妙
  • 网络传输2Kb数据。1微妙

  • 吞吐量
  • 对单位时间内完成的工作量(请求)的量度
  • 在 GC 中:运行用户代码的事件占总运行时间的比例(总运行时间:程序的运行时间+内存回收的时间)
  • 吞吐量为 1-1/(1+n),其中-XX::GCTimeRatio=n

  • 内存占用
  • Java 堆区所占的内存大小

  • 相互间的关系
  • 以高速公路通行状况为例
  • 吞吐量:每天通过高速公路收费站的车辆的数据
  • 并发数:高速公路上正在行驶的车辆的数目
  • 响应时间:车速

JVM监控及诊断命令行工具

无监控、不调优!命令行安装 jdk 的 bin 目录,这些工具用来获取目标 JVM 不同方面、不同层次的信息,帮助开发人员很好地解决 Java 应用程序的一些疑难杂症。

  • 查看正在运行的Java进程:jps
  • jps(Java Process Status):显示指定系统内所有的 HotSpot 虚拟机进程(查看虚拟机进程信息),可用于查询正在运行的虚拟机进程。
  • 对于本地虚拟机进程来说,进程的本地虚拟机 ID 与操作系统的进程 ID 是一致的,是唯一的。
  • 基本使用语法为:jps [options] [hostid]

  • 查看JVM统计信息:jstat
  • jstat(JVM Statistics Monitoring Tool):用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT 编译等运行数据。在没有 GUI 图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。(一般生产环境没gui工具,简单可常用这个)
  • 基本使用语法为:jstat - [-t] [-h] [ []],比如jstat -gc 进程id 1000 10
  • jstat 还可以用来判断是否出现内存泄漏
  • 在长时间运行的 Java 程序中,我们可以运行 jstat 命令连续获取多行性能数据,并取这几行数据中 OU 列(即已占用的老年代内存)的最小值。
  • 然后,我们每隔一段较长的时间重复一次上述操作,来获得多组 OU 最小值。如果这些值呈上涨趋势,则说明该 Java 程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏。

  • 实时查看和修改JVM配置参数:jinfo
  • jinfo(Configuration Info for Java):查看虚拟机配置参数信息,也可用于调整虚拟机的配置参数
  • 基本使用语法为:jinfo [options] pid,比如jinfo -sysprops 进程id

  • 导出内存映像文件&内存使用情况:jmap
  • 获取 dump 文件(堆转储快照文件,二进制文件),它还可以获取目标 Java 进程的内存相关信息,包括 Java 堆各区域的使用情况、堆中对象的统计信息、类加载信息等。
  • 基本使用语法为:
  • jmap [option]
  • jmap [option] <executable
  • jmap [option] [server_id@]

  • 使用1:导出内存映像文件
  • 手动的方式
  • jmap -dump:format=b,file=<filename.hprof>
  • jmap -dump:live,format=b,file=<filename.hprof>

  • 使用2:显示堆内存相关信息
  • jmap -heap 进程id
  • jmap -histo 进程id

  • 使用3:其他作用
  • jmap -permstat 进程id
  • 查看系统的ClassLoader信息
  • jmap -finalizerinfo
  • 查看堆积在finalizer队列中的对象

  • JDK 自带堆分析工具:jhat
  • jhat(JVM Heap Analysis Tool):Sun JDK 提供的 jhat 命令与 jmap 命令搭配使用,用于分析 jmap 生成的 heap dump 文件(堆转储快照)。jhat 内置了一个微型的 HTTP/HTML 服务器,生成 dump 文件的分析结果后,用户可以在浏览器中查看分析结果(分析虚拟机转储快照信息)。
  • 使用了 jhat 命令,就启动了一个 http 服务,端口是 7000,即 http://localhost:7000/,就可以在浏览器里分析。
  • 说明:jhat 命令在 JDK9、JDK10 中已经被删除,官方建议用 VisualVM 代替。
  • 基本适用语法:jhat

  • 打印JVM中线程快照:jstack
  • jstack(JVM Stack Trace):用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪)。线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。
  • 生成线程快照的作用:可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用 jstack 显示各个线程调用的堆栈情况。
  • 基本语法 : jstack [option] pid

  • 多功能命令行:jcmd
  • 在 JDK 1.7 以后,新增了一个命令行工具 jcmd。它是一个多功能的工具,可以用来实现前面除了 jstat 之外所有命令的功能。比如:用它来导出堆、内存使用、查看 Java 进程、导出线程信息、执行 GC、JVM 运行时间等。
  • jcmd -l:列出所有的 JVM 进程
  • jcmd pid help:针对指定的进程,列出支持的所有具体命令
  • jcmd pid 具体命令:显示指定进程的指令命令的数据

  • 远程主机信息收集:jstatd
  • 之前的指令只涉及到监控本机的 Java 应用程序,而在这些工具中,一些监控工具也支持对远程计算机的监控(如 jps、jstat)。为了启用远程监控,则需要配合使用 jstatd 工具。命令 jstatd 是一个 RMI 服务端程序,它的作用相当于代理服务器,建立本地计算机与远程监控工具的通信。jstatd 服务器将本机的 Java 应用程序信息传递到远程计算机。

JVM监控及诊断工具GUI

前面我们学习Arthas也是一种JVM监控及诊断工具GUI,本篇先抛出影子,后续在单独针对

  • JDK自带的工具
  • jconsole:JDK 自带的可视化监控工具。查看 Java 应用程序的运行概况、监控堆信息、永久区(或元空间)使用情况、类加载情况等。
  • 从 Java5 开始,在 JDK 中自带的 java 监控和管理控制台。用于对 JVM 中内存、线程和类等的监控,是一个基于 JMX(java management extensions)的 GUI 性能监控工具。

  • Visual VM:Visual VM 是一个工具,它提供了一个可视界面,用于查看 Java 虚拟机上运行的基于 Java 技术的应用程序的详细信息。
  • VisualVM是–个功能强大的多合一故障诊断和性能监控的可视化工具。
  • 它集成了多个JDK命令行工具,使用VisualVM可用于显示虚拟机进程及进程的配置和环境信息(jps ,jinfo),监视应用程序的CPU、GC、堆、方法区及线程的信息(jstat、jstack)等,替JConsole。
  • 在JDK 6 Update 7以后,Visual VM便作为JDK的一 部分发布(VisualVM 在JDK/bin目录下)。此外,Visual VM也可以作为独立的软件安装。

  • JMC:Java Mission Control,内置 Java Flight Recorder。能够以极低的性能开销收集 Java 虚拟机的性能数据。

  • 第三方工具
  • MAT:MAT(Memory Analyzer Tool)是基于 Eclipse 的内存分析工具,是一个快速、功能丰富的 Java heap 分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。
  • MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如 Sun,HP,SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的 PHD 堆存储文件等都能被很好的解析。
  • 最吸引人的还是能够快速为开发人员生成内存泄漏报表,方便定位问题和分析问题。虽然 MAT 有如此强大的功能,但是内存分析也没有简单到一键完成的程度,很多内存问题还是需要我们从 MAT 展现给我们的信息当中通过经验和直觉来判断才能发现。

  • JProfiler:商业软件,需要付费。功能强大。
  • Flame Graphs(火焰图),在追求极致性能的场景下,了解你的程序运行过程中 cpu 在干什么很重要,火焰图就是一种非常直观的展示 CPU 在程序整个生命周期过程中时间分配的工具和调用找中的 CPU 消耗瓶颈。

此外针对JVM运行时参数和分析GC日志再单独增加专题文档

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里云版GPT官宣,我们问了它10个问题

4月7日&#xff0c;阿里云宣布自研大模型“通义千问”&#xff0c;目前已开始邀请用户测试体验。 阿里达摩院在NLP自然语言处理等前沿科研领域早已布局多年&#xff0c;并于2019年启动大模型研发&#xff0c;通义千问便是其最新成果&#xff0c;相当于阿里云版的“ChatGPT”。 …

EPICS synApps SSCAN模块

1、在这个模块中有什么&#xff1f; 1&#xff09;代码 sscan记录busy记录recDynLink库saveData数据存储客户端scanparm记录 2&#xff09;EPICS数据库 scan数据库scanParms和alignParms数据库 3&#xff09;MEDM显示窗口 scan*.adlscan*_help.adl2、简单扫描 1&#xff0…

Linux系统【Centos7】设置防火墙教程

1. 查看防火墙状态 在终端输入以下命令&#xff1a; systemctl status firewalld 如果状态显示为“active”说明防火墙已经启动&#xff1b;如果状态显示为“inactive”说明防火墙没有启动。 2. 启动防火墙 在终端输入以下命令&#xff1a; systemctl start firewalld 3…

vue3自定义实现可过滤关键字的树形下拉选择框

背景 最近项目中有一个部门选择需求&#xff0c;一开始是用element-plus的级联下拉写的&#xff0c;但是由于层级过深&#xff0c;会出现级联下拉超出屏幕的情况&#xff0c;所以改用树形下拉&#xff0c;但是element没有相关组件&#xff0c;现记录下vue3js自定义实现可以根据…

Vector - CAPL - CRC算法介绍(续)

不常用CRC算法 目录 Crc_CalculateCRC8H2F 代码示例 Crc_CalculateCRC32P4 代码示例 Crc_CalculateCRC64 代码示例 Crc_CalculateCRC8H2F 功能&#xff1a;根据数据计算CRC8H2F的相应校验和。 data&#xff1a;待计算CRC8H2F校验和的数据 dataSize&#xff1a;待计算CRC…

JVM垃圾收集器与HotSpot的算法细节

目录 HotSpot的算法细节实现 根节点枚举 安全点 安全区域 记忆集与卡表 记忆集 作用 卡表&#xff08;Card Table&#xff09; 卡页&#xff08;Card Page&#xff09; 元素变脏&#xff08;Dirty&#xff09; 写屏障 写屏障 写前屏障&#xff08;Pre-Write Barrie…

【数据结构】顺序表

作者&#xff1a;日出等日落 专栏&#xff1a;数据结构 只有毅力才会使我们成功&#xff0c;而毅力的来源又在于毫不动摇&#xff0c;坚决采取为达到成功所需要的手段。 …

Ceph部署

1. 简介 Ceph是一个高性能、可扩容的分布式存储系统&#xff0c;它提供三大功能&#xff1a; 对象存储&#xff1a;提供RESTful接口&#xff0c;也提供多种编程语言绑定。兼容S3、Swift块存储&#xff1a;由RBD提供&#xff0c;可以直接作为磁盘挂载&#xff0c;内置了容灾机…

代码规范(以后会补充)

目录 为什么要规范代码 不规范的代码有什么特点 ​编辑 不规范的坏处 规范代码是什么样的 如何规范代码 1.代码中不要出现莫名其妙的数字 2.深度嵌套 3.注释 4.避免创建大函数 5.重复代码 6.变量命名 7.函数命名 8.命名时注意动词的使用 9. 常量值所有都大写 10. 避免变…

PMP备考资料:如何掌握PMP应考中的计算题?

计算题总体来说考得非常简单&#xff0c;题量也少&#xff0c;有时候只考3道、4道简单计算。所以这部分内容大家要细心严谨&#xff0c;不要因为粗心而丢掉分数。 01三点估算 通过考虑估算中的不确定性和风险&#xff0c;可以提高活动持续时间估算的准确性。这个概念源自计划…

映射的概念以及用法

映射的概念以及用法前言映射的定义映射的应用前言 在数学里&#xff0c;映射是个术语&#xff0c;指两个元素的集之间元素相互 “对应”的关系&#xff0c;为名词。映射&#xff0c;或者射影&#xff0c;在数学及相关的领域经常等同于函数&#xff0c;函数是从非空数集到非空数…

PyCharm解决Git冲突

技术背景 在前面的一篇博客中&#xff0c;我们介绍了Fork到自己名下的本地仓库如何与远程原始仓库创建链接的方法。在这篇文章中&#xff0c;我们将要讲解如何应对在这种异步开发的过程中经常有可能会遇到的Git冲突问题&#xff0c;在Pycharm这个专业的Python开发工具中集成了一…

网络基础概念

本文目标&#xff1a; ①了解网络发展背景, 对局域网/广域网的概念有基本认识; ②了解网络协议的意义, 重点理解TCP/IP五层结构模型; ③学习网络传输的基本流程, 理解封装和分用; 1.计算机网络背景 OS与网络 在整个计算机体系中&#xff0c;是先由操作系统&#xff0c;再有网…

Windows下使用SSH密钥实现免密登陆Linux服务器

工具&#xff1a; win10、WinSCP 生成ssh密钥&#xff1a; 打开终端&#xff0c;使账号密码登录&#xff0c;输入命令 ssh-keygen -t rsa 会提示密钥存放路径&#xff0c;一般存放在默认路径&#xff0c;直接回车即可&#xff0c;中间会提示输入密码&#xff0c;这里需要注…

CC攻击原理以及如何防御策略

CC攻击原理以及如何防御策略 CC 攻击是一种 DDoS&#xff08;分布式拒绝服务&#xff09;&#xff0c;它似乎比其他 DDoS 攻击更具技术性。在这种攻击中&#xff0c;看不到假IP&#xff0c;看不到特别大的异常流量&#xff0c;但会导致服务器无法正常连接。 很多创业公司辛辛苦…

你是真的“C”——C语言测评总结

你是真的“C”——C语言测评总结&#x1f60e;前言&#x1f64c;BC146 添加逗号总结撒花&#x1f49e;&#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭&#xff1a;全神贯注的上吧&#xff01;&#xff01;&#xff01; &#x1f60a;作者简介&#xf…

TreEnhance: A Tree Search Method For Low-Light Image Enhancement 论文阅读笔记

这是2023年PR这个期刊的论文主要思想是&#xff0c;利用一系列预定义好的操作序列来进行增强&#xff0c;然后利用强化学习来学习增强序列的预测。所以训练阶段有两个交替进行的阶段&#xff0c;一个是蒙特卡洛树搜索阶段&#xff0c;第二个是训练深度强化学习的阶段。而测试的…

中级软件设计师备考---计算机组成与体系结构3

目录①磁盘工作原理②计算机总线③系统可靠性分析④校验码CRC循环校验码海明校验码①磁盘工作原理 计算题 ②计算机总线 概念题 ③系统可靠性分析 计算可靠度 ④校验码 码距&#xff1a;是指两个码字之间的不同位数。例如&#xff0c;1010和1111之间的码距是2&#xff0c…

160. 相交链表 ——【Leetcode每日一题】

160. 相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c…

生成式人工智能所面临的问题有哪些?

在生成式人工智能中工作需要混合技术、创造性和协作技能。通过发展这些技能&#xff0c;您将能够在这个令人兴奋且快速发展的领域应对具有挑战性的问题。 生成式人工智能是指一类机器学习技术&#xff0c;旨在生成与训练数据相似但不完全相同的新数据。 换句话说&#xff0c;…