Java学习篇之JVM 调优

Java学习篇之JVM 调优

  • 一、JVM 是什么?
  • 二、JVM 官方参数建议
  • 三、JVM调优的场景
  • 四、如何监控JVM
  • 五、JVM调优的流程步骤
    • 1. 明确优化目标
    • 2. 监控和分析
    • 3. 确定调优参数
    • 4. 实施调优策略
    • 5. 持续观察和调整
    • 6. 定期评估和优化

一、JVM 是什么?

JVM,全称Java Virtual Machine(Java虚拟机),是一个能够运行Java字节码的抽象计算机。
JVM是Java跨平台特性的核心。Java源代码在编译成字节码后,可以在任何支持Java的平台上运行,只要该平台安装了相应的JVM。这是因为JVM将Java字节码转换成特定平台上的机器码来执行,从而实现了“一次编写,到处运行”的跨平台特性。

二、JVM 官方参数建议

JVM 经过这么多年的发展和验证,整体是非常健壮的。个人认为99%的情况下,基本用不到 JVM 调优。
通常来说,我们的 JVM 参数配置大多还是会遵循 JVM 官方的建议,例如:

1. 堆内存设置

参数描述官方建议/说明
-Xms设置JVM的初始堆大小默认为物理内存(运行内存)的1/64;对于高并发应用,建议与-Xmx相同
-Xmx设置JVM的最大堆大小默认为物理内存(运行内存)的1/4
-Xmn设置年轻代的初始和最大大小默认为整个堆的3/8;或使用-XX:NewSize/-XX:MaxNewSize分别设置

2. 年轻代与老年代比例

参数描述官方建议/说明
-XX:NewRatio设置年轻代与老年代的比例默认值为2(即老年代是年轻代的2倍)
-XX:SurvivorRatio设置Eden区与一个Survivor区的大小比例默认值为8,表示Eden区与Survivor区的比例为8:1

3. 线程堆栈设置

参数描述官方建议/说明
-Xss设置每个线程的堆栈大小JDK5.0后默认1MB;小型应用可能128KB足够,大型应用建议256KB

4. 非堆内存设置

参数描述官方建议/说明
-XX:PermSize设置持久代的初始大小(JDK8已弃用)JDK8前用于控制方法区内存大小
-XX:MaxPermSize设置持久代的最大大小(JDK8已弃用)JDK8前用于控制方法区内存大小
-XX:MetaspaceSize设置元空间的初始大小(JDK8及以后)替代了PermSize,用于存放类的元数据
-XX:MaxMetaspaceSize设置元空间的最大大小(JDK8及以后)替代了MaxPermSize

5. 垃圾收集器设置

参数描述官方建议/说明
-XX:+UseSerialGC使用串行垃圾收集器默认GC方式,适用于小型应用和单处理器环境
-XX:+UseParNewGC在年轻代中使用并行线程进行垃圾收集可以与CMS GC一起使用
-XX:+UseParallelGC在年轻代中使用并行垃圾收集器适用于多处理器系统
-XX:+UseParallelOldGC在老年代中使用并行垃圾收集器与-XX:+UseParallelGC一起使用
-XX:+UseConcMarkSweepGC使用CMS垃圾收集器在GC运行时对应用程序影响较小

6. 辅助信息设置

参数描述官方建议/说明
-XX:+PrintGCDetails打印垃圾收集的详细情况用于调试和性能分析
-Xloggc:filename将GC日志信息记录到指定文件便于分析和监控JVM的垃圾回收行为

7. 其他重要参数

参数描述官方建议/说明
-XX:MinHeapFreeRatio设置GC事件后允许的最小可用堆空间百分比控制JVM何时扩展堆大小
-XX:MaxHeapFreeRatio设置GC事件后允许的最大可用堆空间百分比控制JVM何时收缩堆大小
-XX:MaxDirectMemorySize设置Direct ByteBuffer分配的堆外内存的最大大小当达到此大小时,将触发Full GC

请注意,这些建议是基于Oracle JDK的通用指南,并且可能会随着JVM版本的更新而有所变化。
在实际应用中,可能还需要根据具体的应用场景、硬件环境和性能需求进行进一步的调整和优化。
同时,也需要注意参数的兼容性和稳定性问题。

三、JVM调优的场景

主要就是出现以下情况时,就需要注意对JVM进行调优了

  1. 当应用程序运行缓慢或出现卡顿,或是偶尔响应慢
  2. 应用程序频繁出现内存溢出(OutOfMemoryError)或内存泄漏等问题,

四、如何监控JVM

JVM监控工具分为JDK自带工具和第三方工具两大类。

  • JDK自带工具(常用的):jconsole、visualvm
  • 第三方工具(常用的):JProfiler、YourKit

JDK自带工具常用命令:

  • jstack pid: 打印堆栈相关执行信息,可以用于死锁发现。
  • jinfo pid: 打印进程的启动详细参数、JVM正在使用的参数。
  • jstat -gc pid: 打印各个分代的内存使用情况。可以每个一段时间打印一次。
  • visualvm: windows图形化界面,不常用。上线之前内测可以使用
  • jmap: 如果内存特别大,jmap会导致线程的停止,所以线上不能使用
    线上时不能dump下来文件,因为文件可能很大(堆内存占了多少文件就有多大),dump时java程序会暂停,线上不能dump。
    jmap -histo pid | head -n 20 :查找有多少对象产生,及对象占用的内存,对象的名称。可用于内存泄露导致的OOM。

五、JVM调优的流程步骤

JVM调优流程步骤可以归纳为以下几点:

1. 明确优化目标

在开始调优之前,首先需要明确优化的目标。这包括响应时间、吞吐量、内存使用率等指标。明确目标后,可以更有针对性地进行调优。

2. 监控和分析

  1. 使用监控工具:利用Java VisualVM、JConsole、JProfiler等监控工具,分析CPU使用率、内存使用情况和垃圾回收频率等指标。

JDK自带工具常用命令:

  • jstack pid: 打印堆栈相关执行信息,可以用于死锁发现。
  • jinfo pid: 打印进程的启动详细参数、JVM正在使用的参数。
  • jstat -gc pid: 打印各个分代的内存使用情况。可以每个一段时间打印一次。
  • visualvm: windows图形化界面,不常用。上线之前内测可以使用
  • jmap: 如果内存特别大,jmap会导致线程的停止,所以线上不能使用
    线上时不能dump下来文件,因为文件可能很大(堆内存占了多少文件就有多大),dump时java程序会暂停,线上不能dump。
    jmap -histo pid | head -n 20 :查找有多少对象产生,及对象占用的内存,对象的名称。可用于内存泄露导致的OOM。
  1. 分析GC日志:通过GC日志,了解垃圾回收的频率、停顿时间以及内存使用情况,帮助定位性能瓶颈。

例如:

-Xloggc:/path/to/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps

这些选项将GC日志记录到指定的文件(/path/to/gc.log),并打印详细的GC信息和时间戳。

然后,我们可以分析GC日志以了解垃圾回收的频率、停顿时间和内存使用情况。例如,我们可以查>找Full GC的发生频率和每次Full GC的停顿时间。

3. 确定调优参数

根据监控和分析的结果,确定需要调整的JVM参数。常见的JVM参数包括:

  1. 堆内存设置:通过-Xms和-Xmx设置初始和最大堆内存大小。

例如:

-Xms512m -Xmx512m

这将初始堆内存设置为512m,最大堆内存设置为512m。两者最好一致

  1. 垃圾收集器选择:选择合适的垃圾收集器,如G1、CMS等,以优化内存管理。

例如:
选择G1垃圾收集器:以优化内存管理和减少停顿时间。

-XX:+UseG1GC

调整G1垃圾收集器的参数:以进一步优化性能。

-XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=35

这将G1垃圾收集器的目标停顿时间设置为200毫秒,并将触发并发GC的堆占用百分比设置为35%。

  1. 线程栈大小:通过-Xss设置每个线程的堆栈大小,以减少线程上下文切换的开销。

4. 实施调优策略

  1. 调整JVM参数:根据确定的调优参数,调整JVM的启动参数。

例如:如果我们在Linux系统上使用java命令启动应用程序,我们可以这样设置:

java -Xms512m -Xmx512m -Xloggc:/path/to/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=35 -jar myapp.jar
  1. 优化代码:减少不必要的对象创建、使用高效的数据结构、避免过度的同步等,都可以显著提升应用的性能。

5. 持续观察和调整

  1. 持续监控:在调整参数和优化代码后,使用监控工具持续观察应用的性能变化。
  2. 对比性能指标:通过对比调优前后的性能指标,确认是否达到了预期的优化目标。
  3. 重新评估和调整:如果没有达到目标,可能需要重新评估调优策略,进行进一步的调整。

6. 定期评估和优化

性能调优是一个持续的过程。随着应用的演变和用户负载的变化,可能需要定期重新评估和调整JVM参数。定期的性能测试和监控可以帮助及时发现潜在问题,确保系统的稳定性和高效性。

参考文章
【1】面试官:如何进行 JVM 调优(附真实案例)
【2】【JVM】JVM 实战调优指南赋案例(保姆篇)
【3】JVM调优实例记录
【4】【Java】JVM调优操作手册(实战篇)
【5】JVM性能优化实战手册:从监控到调优策略

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

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

相关文章

STM32单片机WIFI语音识别智能衣柜除湿消毒照明

实践制作DIY- GC0196-WIFI语音识别智能衣柜 一、功能说明: 基于STM32单片机设计-WIFI语音识别智能衣柜 二、功能介绍: STM32F103C系列最小系统板LCD1602显示器ULN2003控制的步进电机(柜门开关)5V加热片直流风扇紫外消毒灯DHT11…

qt QShortcut详解

1、概述 QShortcut是Qt框架中的一个类,它提供了一种创建键盘快捷键的方式。通过QShortcut,开发者可以将特定的键盘组合(如CtrlC、AltF4等)与应用程序中的动作(如复制、关闭窗口等)关联起来。当用户在应用程…

Seldon Core大模型部署详解

一 Seldon Core定义 Seldon Core 目前是机器学习模型部署领域最受欢迎的方案之一,由 Seldon 公司开源和维护,旨在为不同框架下训练出来的模型(Tensorflow,Pytorch,SKLearn,XGBoost)提供一套相对…

Docker 的常用命令有哪些?

Docker 有很多命令,这里列一下比较常用的: dockerrun:启动一个新的容器 docker ps:列出正在运行的容器 docker ps-a:列出所有容器 docker stop:停止正在运行的容器 docker start:启动已停止的容器 docker rm:删除容器 dockerimages:列出本地镜像 docker pu:…

C语言笔记(字符串函数,字符函数,内存函数)

目录 前言 1.字符串函数 1.1.strlen 1.2.strcpy 1.3.strcat 1.4.strcmp 1.5.strncpy 1.6.strncat 1.7.strncmp 1.8.strstr 1.9.strtok 1.10.strerror 2.字符函数 2.1字符分类函数 2.2字符转换函数 3.内存函数 3.1.mencpy 3.2.memmove 3.3.memcmp 前言 本文重…

Debian 12环境里部署nginx步骤记录

前言 浅记录一下 在Debian 12环境里安装nginx的过程,这个过程并没有特别顺利,有遇到各种报错,这些报错,我也会记录进来;方便自己后续查看以及供需要的小伙伴参考吧~~ 主要参考资料:https://blog.csdn.ne…

详解基于C#开发Windows API的SendMessage方法的鼠标键盘消息发送

在C#中,SendMessage方法是一个强大的工具,它允许我们与Windows API交互,模拟键盘和鼠标事件。本文将详细介绍如何使用SendMessage方法来发送鼠标和键盘消息。 1. SendMessage方法概述 SendMessage是Windows API中的一个函数,它用…

单片机入门知识

1单片机系统的int是16位 计算机系统的int是32位(数据总线) 2的16次方是65536 所以在单片机中,如果表示一个正整数,这个数字的范围是0~65535,总共有65536种可能 2内存条用于存储计算机运行时的数据,是连接…

ABAP:SET CURSOR FIELD设置鼠标焦点

SET CURSOR FIELD <字段名>&#xff1a;设置鼠标焦点到该字段 SET CURSOR 设置到鼠标焦点列还是行 SET CURSOR LINE 设置鼠标焦点到行 GET CURSOR field <字段名> &#xff1a;这个相对应的获取鼠标焦点得到的字段

Unity Windows 2023 Release-Notes

&#x1f308;Unity Windows 2023 Release-Notes 本文信息收集来自自动搜集工具&#x1f448; 版本更新内容2023.2.13Windows: Fixed Double backslash becoming single backslash when passing a Network path as a command line argument.(UUM-55979)2023.2.9Windows: Fixed…

数据挖掘(十)

数据挖掘&#xff08;十&#xff09; 文章目录 数据挖掘&#xff08;十&#xff09;物体分类应用场景和目标深度神经网络应用 对于去欸的那个图像中的物体&#xff0c;我们使用像素值作为神经网络的输入值&#xff0c;自动找到有用的像素组合&#xff0c;形成更高层级的特征&am…

ArcGIS从Excel表格文件导入XY数据并定义坐标系与投影的方法

本文介绍在ArcMap软件中&#xff0c;从Excel表格文件中批量导入坐标点数据&#xff0c;将其保存为.shp矢量格式&#xff0c;并定义坐标系、转为投影坐标系的方法。 已知我们有一个Excel表格文件&#xff08;可以是.xls、.xlsx、.csv等多种不同的表格文件格式&#xff09;&#…

三周精通FastAPI:38 针对不同的编程语言来生成客户端

官方文档&#xff1a;https://fastapi.tiangolo.com/zh/advanced/generate-clients/ 生成客户端 因为 FastAPI 是基于OpenAPI规范的&#xff0c;自然您可以使用许多相匹配的工具&#xff0c;包括自动生成API文档 (由 Swagger UI 提供)。 一个不太明显而又特别的优势是&#…

Linux【基础篇】T

--已经不知道幸福是什么味道了 Linux命令行 linux命令提示符 linux目录结构 Windows的目录结构是N个顶点&#xff0c;可以是C盘 可以是D盘 可以是E盘 往下。 linux的目录结构是只有一个订单 &#xff0c;像一颗倒状的树木一样的。 linux常用目录含义 /etc目录下一些重要的配置…

全局注册和局部注册

在 Vue 3 中&#xff0c;你可以选择全局注册或局部注册组件。这两种方法各有优缺点&#xff0c;适用于不同的场景。 全局注册 全局注册的组件可以在应用的任何地方使用&#xff0c;不需要在每个使用它的组件中单独导入。这使得全局注册非常适合那些在整个应用中频繁使用的组件…

Mesh网格

Mesh(网格) 定义&#xff1a;Mesh 是一个包含顶点、三角形、顶点法线、UV坐标、颜色和骨骼权重等数据的对象。它定义了3D模型的几何形状。 功能&#xff1a; 顶点&#xff08;Vertices&#xff09;&#xff1a;构成3D模型的点。 三角形&#xff08;Triangles&#xff09;&…

JavaScript 代码规范

JavaScript 代码规范 JavaScript 是一种广泛使用的编程语言&#xff0c;尤其在网页开发中扮演着核心角色。为了确保代码的质量、可维护性和团队协作效率&#xff0c;遵循一定的代码规范变得至关重要。本文将详细介绍 JavaScript 代码规范&#xff0c;包括命名规则、编码风格、…

【网络安全 | 服务器】Nginx功能快速入门

未经许可,不得转载。 文章目录 1、静态HTTP服务器2、反向代理服务器3、负载均衡4、虚拟主机5、FastCGINginx 是一个高效、轻量级的 Web 服务器和反向代理服务器,广泛应用于处理高并发请求。 1、静态HTTP服务器 Nginx 可以作为一个高效的静态 HTTP 服务器来提供文件,如 HTM…

【从零开始的LeetCode-算法】540. 有序数组中的单一元素

给你一个仅由整数组成的有序数组&#xff0c;其中每个元素都会出现两次&#xff0c;唯有一个数只会出现一次。 请你找出并返回只出现一次的那个数。 你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。 示例 1: 输入: nums [1,1,2,3,3,4,4,8,8] 输出: 2示例…

传输协议设计与牧村摆动(Makimoto‘s Wave)

有一条活鱼和一条死鱼&#xff0c;你准备怎么做&#xff0c;你会将活鱼红烧或将死鱼清蒸吗&#xff1f;好的食材只需要最简单的烹饪&#xff0c;不好的食材才需要花活儿。 我此前的文字几乎都在阐述一个观点&#xff0c;广域网就是那条死鱼&#xff0c;数据中心则是那条活鱼。…