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

news2025/7/11 14:54:33

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.coloradmin.cn/o/406246.html

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

相关文章

Day16【元宇宙的实践构想04】—— 元宇宙的安全

&#x1f483;&#x1f3fc; 本人简介&#xff1a;男 &#x1f476;&#x1f3fc; 年龄&#xff1a;18 ✍今日内容&#xff1a;《元宇宙的实践构想》04——元宇宙的安全 ❗❗❗从1.31日开始&#xff0c;阿亮每天会查阅一些元宇宙方面的小知识&#xff0c;和大家一起分享。一是由…

ChatGPT背后的技术和多模态异构数据处理的未来展望——我与一位资深工程师的走心探讨

上周&#xff0c;我和一位从业三十余年的工程师聊到ChatGPT。 作为一名人工智能领域研究者&#xff0c;我也一直对对话式大型语言模型非常感兴趣&#xff0c;在讨论中&#xff0c;我向他解释这个技术时&#xff0c;他瞬间被其中惊人之处所吸引&#x1f64c;&#xff0c;我们深…

读书笔记——《再见,平庸时代》

为什么会看这本书 《马斯克》这本书中&#xff0c;最后几段介绍了一下经济学家和作者泰勒考恩的两本书《大停滞》《再见&#xff0c;平庸时代》。《大停滞》讲的是美国这40年发展为何停滞&#xff0c;我当然不太关心这种内容。但是《再见&#xff0c;平庸时代》不是对历史的研究…

springboot 东方通(tongweb)替换tomcat

一.修改pom.xml文件依赖 1.排除springboot中内置的tomcat依赖 2.添加tongweb-spring-boot-starter和tongweb-embed依赖 特别说明下&#xff1a;我这里所有依赖的包都传到了私有仓库&#xff0c;直接复制到pom.xml文件会import失败。 <!-- SpringBoot Web容器 --> <d…

分享Python7个爬虫小案例(附源码)

本次的7个python爬虫小案例涉及到了re正则、xpath、beautiful soup、selenium等知识点&#xff0c;非常适合刚入门python爬虫的小伙伴参考学习。注&#xff1a;若涉及到版权或隐私问题&#xff0c;请及时联系我删除即可。 1.使用正则表达式和文件操作爬取并保存“某吧”某帖子…

【uniapp小程序实战】—— 使用腾讯地图获取定位

文章目录&#x1f34d;前言&#x1f34b;正文1、首先看官网uni.getLocation(OBJECT)#注意2、腾讯位置服务平台申请密钥和下载SDK2.1 申请开发者秘钥2.2 开通webserviceAPI服务2.3 下载微信小程序JavaScriptSDK2.4 安全域名设置3、配置manifest.json文件4、示例代码展示4.1 引用…

如何用Python求解微分方程组

文章目录odeint简介示例odeint简介 scipy文档中将odeint函数和ode, comples_ode这两个类称为旧API&#xff0c;是scipy早期使用的微分方程求解器&#xff0c;但由于是Fortran实现的&#xff0c;尽管使用起来并不方便&#xff0c;但速度没得说&#xff0c;所以有的时候还挺推荐…

JavaScript基础(详细总结)

目录 1、JavaScript简介 1.2、JavaScript的发展史 1.3、JavaScript的功能 1.4、JavaScript的特点 1.5、JavaScript组成 2、JavaScript基础语法 2.1、HTML引入JS 2.1.1、内部引入 2.1.2、外部引入 2.2、JS输出数据的三种方式 2.2.1、浏览器弹窗 2.2.2、输出HTML页面…

IDEA实现前端页面登录,注册、增、删、改、查操作-完整版

分层思想&#xff1a;entity层&#xff1a;存放实体类vo层&#xff1a;消息模型&#xff08;重复使用的一些属性&#xff09;mapper层&#xff1a;接口&#xff08;写方法的&#xff09;mapper.xml:MyBatis与数据库相关的一些内容controller(web)层&#xff1a;接收前端传回的参…

谈谈ES5和ES6的区别

我们都知道JavaScript是由三部分组成&#xff1a; 1. ECMAScript(核心)&#xff1a;规定了语言的组成部分>语法、类型、语句、关键字、保留字、操作符、对象 2. BOM(浏览器对象模型): 支持访问和操作浏览器窗口&#xff0c;可以控制浏览器显示页面以外的部分。 3. DOM(文…

基于Python构建机器学习Web应用

目录 一、内容介绍 1.Onnx模型 ①skl2onnx库安装 2.Netron安装 二、模型构建 1.数据加载 2.划分可训练特征与预测标签 3.训练模型 ①第三方库导入 ②数据集划分 ③SVC模型构建 ④精度评价 二、模型转换及可视化 1.参数配置 2.Onnx模型生成 3.可视化模型 四、构…

报错ValidationError: Progress Plugin Invalid Options

背景&#xff1a;我改了文件的名字 他很多配置都没有了 我只能重新来 中途删了删掉node_modules和package-lock.json 也找了很多方法来重复配置着两个文件 最快的方法是 npm i -D vue 后面复原了之后又出现了很多问题 一直困恼我的是下面那个图片内容 背景&#xff1a;他…

Java Web入门 Web环境的搭建

文章目录 一、JDK开发工具包 a、下载JDK b、如何安装 c、配置Java环境变量。 d、测试环境变量是否安装成功 二、下载Tomcat服务器 a、Tomcat是什么&#xff1f;为啥要用它&#xff1f; b、如何下载 c、了解Tomcat的目录 d、如何知道自己Tomcat服务器有没有问题呢&#…

在 js 中,reduce() 的详解 以及使用方法

reduce&#xff08;&#xff09;&#xff1a; reduce&#xff08;&#xff09;方法为归并类方法&#xff0c;最常用的场景就是&#xff0c;计算数组中的每一项的总和。 reduce&#xff08;&#xff09; 方法会遍历数组的每一项&#xff0c;他接收两个参数&#xff1a; 第一个…

22.信息系统安全管理-策略7定.方案.安全体系架构.PKI.PMI

信息系统的安全威胁分成七类&#xff0c;从风险源的角度划分&#xff0c;可以将安全威胁划分为&#xff1a;自然事件风险、人为事件风险、软件风险、软件过程风险、项目管理风险、应用风险、用户使用风险。 信息系统安全四个层次:设备安全、数据安全、内容安全、行为安全。数据…

vite打包配置(静态资源合并打包/清除log/gzip压缩/ENV配置等)

2022/6/2更新 传了一下本项目代码,文章里写到的基本都有用到,可以clone了看一下 下载地址https://github.com/shinjie1210/vite-config.git---------------------------------------------------------------------------------------------------------------------------- …

基于vue的uni-app生态——学习笔记001

目录 vue的简介 什么是vue.js vue相比传统的js开发优势有哪些 vue的优势 与传统的开发文件相比的类型变换 与传统的开发相比开发文件内部架构的变化 uni-app生态&#xff08;编辑器的使用&#xff09; 编辑器的下载 编辑器的使用 基于vue开发的uni-app生态的文件结构…

CANoe中使用CAPL刷写流程详解(Trace图解)(CAN总线)

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…

Vue初入,了解Vue的发展与优缺点

作者简介&#xff1a;一名计算机萌新、前来进行学习VUE,让我们一起进步吧。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;我叫于豆豆吖的主页 前言 从本章开始进行Vue前端的学习&#xff0c;了解Vue的发展&#xff0c;以及背后的故事。 一.vue介…

一、Django基础介绍

一、Django介绍 Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。Django 是一个开放源代码的 Web 应用框架&#xff0c;由 Python 写成。Django 遵守 BSD 版权&#xff0c;初次发布于 2005 年 7 月, 并于 2008 年 …