JVM调优参数+Visual GC 插件安装及使用,jvm分析

news2024/11/17 7:17:38

调优的目的是什么呢?

1.就是让系统更加的丝滑,让用户体验变得更好。
2.提升系统的性能,提高效率,充分利用jvm内存。

更多参考->JVM常用调优参数

一.JVM参数配置位置

1.java.lang.OutOfMemoryError: Java heap space 解决方法,Java堆异常,需要配置jvm参数,尽量减少GC垃圾回收的次数

2.java.lang.OutOfMemoryError: Java heap space和java.lang.StackOverflowError:java.lang.OutOfMemoryError:java堆空间和栈溢出

这个问题的根源是jvm虚拟机的默认Heap大小是64M,可以通过设置其最大和最小值来实现.设置的方法主要是几个.

1.可以在windows 更改系统环境变量

加上

JAVA_OPTS=-Xms64m -Xmx512m

2.如果用的tomcat,在windows下,可以在
C:\tomcat5.5.9\bin\catalina.bat 中加上:

set JAVA_OPTS=-Xms64m -Xmx256m

位置在: rem Guess CATALINA_HOME if not defined 这行的下面加合适,或者是在setlocal下面添加,便于查看

3.如果是linux系统
Linux 在{tomcat_home}/bin/catalina.sh的前面,加

set JAVA_OPTS='-Xms64 -Xmx512'

spingboot项目启动,可在VM options项配置,tomcat修改catalina.bat(.sh),或者是配置系统环境变量均可,看你喜欢

在这里插入图片描述

二.JVM参数详细配置

对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块。Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。

1).JVM内存结构

在这里插入图片描述

在这里插入图片描述

由上图可以清楚的看到JVM的内存空间分为3大部分

  1. 堆内存 :所有new对象都放在堆里,这也是JVM优化的重点

  2. 栈内存:也叫线程栈,是每个线程独立分配的内存空间,存储的包括局部变量,操作数,动态链接,方法出口。它和堆的关系其实是堆的指针引用

  3. 本地方法栈:为虚拟机用到的Native方法服务。Native方法是java通过JNI直接调用本地C/C++库,可以认为是暴露给java的本地接口。

  4. 方法区:类装载系统会把class信息放到方法区,通过字节码引擎执行。会放常量(运行时常量池,那么什么是静态常量池),静态变量,类元信息。jdk8以后就叫元空间。

其中栈内存可以再细分为java虚拟机栈和本地方法栈,堆内存可以划分为新生代和老年代,新生代中还可以再次划分为Eden区、From Survivor区和To Survivor区。
其中一部分是线程共享的,包括 Java 堆和方法区;另一部分是线程私有的,包括虚拟机栈和本地方法栈,以及程序计数器这一小部分内存。

2) 堆内存(Heap)

在这里插入图片描述

所有的new对象最开始都放到Eden(伊甸)区,当Eden区沾满之后,JVM会进行一次minor gc,将发现依然存活的对象放到Survivor区,同时讲分代年龄+1(存储在object header里面),会清理eden和form区域,通过复制等算法再次将存活对象放到to区域,依次类推来回复制,当年轻代年龄达到15时,会挪到老年代,比如静态变量,数据库连接池,缓存就属于“老不死”。当老年代内存被占满时,就会触发full gc,full gc会对整个堆进行垃圾回收,因此非常耗时,时间很长,我们要尽量降低full gc的频次

full gc:完整垃圾回收,整个堆进行垃圾回收
minor gc:局部回收,参考下图,仅回收新生代中的Eden

注意:old区内存满了后,就会触发full gc

在这里插入图片描述

minor gc如何进行垃圾回收呢,这里面运用到一个可达性分析算法,里面有一个GC roots根的概念很关键,要理解一下,gc会根据该算法找出该对象的整条GC root链,定义为有效存活对象,会移动到survivor区域;剩下的对象由于找不到对象引用,因此定义为无效对象,从而进行回收。具体如下

在这里插入图片描述

  1. 对于大多数应用来说,Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块
  2. Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存
  3. 堆内存是所有线程共有的,可以分为两个部分:年轻代和老年代
  4. 下图中的Perm代表的是永久代,但是注意永久代并不属于堆内存中的一部分,同时jdk1.8之后永久代已经被移除,JDK1.8之后永久代部分称为Metaspace(元空间)
  5. 新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 ),默认的,Eden : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio来设定 ),即: Eden = 8/10 的新生代空间大小,from = to = 1/10 的新生代空间大小。

在这里插入图片描述

old区内存满了后,就会触发full gc,但是发现引用还在(list还是运行),因此没法回收,但是死循环又一直在new对象,old区无内存可用,于是就OOM

  • full gc的时候针对整个heap进行寻找垃圾对象,因此会停顿用户线程(STW)。为什么要停止呢,如果不停止的话,意味着回收线程和用户线程同步执行,回收线程会认为用户线程的内存不是垃圾对象,因此不予理会,但如果用户线程很快执行完,它使用的对象就变成垃圾对象了,这时候回收线程不知道该如何处理,因此为了更好的控制内存,full gc的时候,必须暂停用户线程,回收完成后,再恢复用户线程。
  • 因此问题就出现了,如果频繁的full gc,而且收集时间非常长(因为针对整个堆内存回收)就会频繁的停止用户线程,导致系统功能暂时不可用,也就是卡顿现象或无响应。因此优化的点就一目了然:减少full gc次数,让年轻代去收集释放垃圾对象。

在这里插入图片描述

3) 栈的核心组成部分

在这里插入图片描述

  • 局部变量表: 用于存放方法中的局部变量和参数
  • 操作数栈: 用于存放方法执行过程中产生的中间结果
  • 动态链接:方法区里面的符号引用转为直接引用(即:给出地址)
  • 方法出口:记录当前执行方法执行完毕后返回主方法的下一行位置

4) 方法区(Method Area)

方法区也称"永久代",它用于存储虚拟机加载的类信息、常量、静态变量、是各个线程共享的内存区域。

在JDK8之前的HotSpot JVM,存放这些”永久的”的区域叫做“永久代(permanent generation)”。永久代是一片连续的堆空间,在JVM启动之前通过在命令行设置参数-XX:MaxPermSize来设定永久代最大可分配的内存空间,默认大小是64M(64位JVM默认是85M)。

随着JDK8的到来,JVM不再有 永久代(PermGen)。但类的元数据信息(metadata)还在,只不过不再是存储在连续的堆空间上,而是移动到叫做“Metaspace”的本地内存(Native memory。

方法区或永久代相关设置

  • -XX:PermSize=64MB 最小尺寸,初始分配
  • -XX:MaxPermSize=256MB 最大允许分配尺寸,按需分配
  • XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled 设置垃圾不回收 默认大小
  • -server选项下默认MaxPermSize为64m
  • -client选项下默认MaxPermSize为32m

5) JVM内存参数设置

在这里插入图片描述

  • -Xms设置堆的最小空间大小。
  • -Xmx设置堆的最大空间大小。
  • -Xmn:设置年轻代大小
  • -XX:NewSize设置新生代最小空间大小。
  • -XX:MaxNewSize设置新生代最大空间大小。
  • -XX:PermSize设置永久代最小空间大小。
  • -XX:MaxPermSize设置永久代最大空间大小。
  • -Xss设置每个线程的堆栈大小
  • -XX:+UseParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。
  • -XX:ParallelGCThreads=20:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。

在这里插入图片描述

典型JVM参数配置参考:

  • java-Xmx3550m-Xms3550m-Xmn2g-Xss128k
  • -XX:ParallelGCThreads=20
  • -XX:+UseConcMarkSweepGC-XX:+UseParNewGC

-Xmx3550m:设置JVM最大可用内存为3550M。

-Xms3550m:设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

-Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小+年老代大小+持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,官方推荐配置为整个堆的3/8。

-Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大 小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000 左右。

三.Visual GC 插件安装及使用

jvm分析工具,安装的jdk的bin目录下

jdk1.8.0_31\bin

1.jvisualvm.exe
2.jconsole.exe

1.下载安装

点击下载VisualVM软件

在这里插入图片描述
由于我的是mac系统,因此我下载下面这个dmg文件,如果你是windows系统,下载上面那个zip文件,windows系统的是zip压缩包,解压即可,无需安装,找到bin目录下的visualvm.exe文件双击即可启动;如果是mac系统的dmg文件,需要下载后安装启动。

2.安装Visual GC插件

上面下载完成之后,解压缩包,执行文件夹里面bin下面的visualvm.exe应用程序

在这里插入图片描述

点击菜单Tools,选择Pulgins,在第二个选项中找到Visual GC,选中,点击Install,然后一路下一步即可安装成功,由于本人已经安装,所以未展示Visual GC,如下图:

在这里插入图片描述
插件界面介绍

安装完插件后重启软件,然后打开idea,随后便可以在左边了Local中看到启动的idea应用,双击即可进入监控页面,如下图:

在这里插入图片描述
右边就是Visual GC 插件的主要界面了,我们可以看到软件运行时的内存变化情况:

在这里插入图片描述

下面对上图中的各个窗口区域做简单介绍,整个界面分为三个区域,分别为:Spaces、Graphs和Histogram。

1.Spaces窗口
在这里插入图片描述
上图是呈现了程序运行时我们比较关注的几个区域的内存使用情况:

  • Metaspace:方法区,如果JDK1.8之前的版本,就是Perm,JDK7和之前的版本都是以永久
  • (PermGen)来实现方法区的,JDK8之后改用元空间来实现(MetaSpace)。
  • Old:老年代
  • Eden: 新生代Eden区
  • S0和S1:新生代的两个 Survivor 区

2.Graphs窗口

该窗口区域包含8个图标,以时间为横坐标动态展示各个指标的运行状态
在这里插入图片描述
下面从上往下对上图中的各个图标表及其状态进行说明:

  • Compile Time:编译情况 24266 compoles - 39.416s 表示编译总数为24266,编译总耗时为39.416s。 一个脉冲表示一次JIT编译,脉冲越宽表示编译时间越长。
  • Class Loader Time:类加载情况 49052 loaded,39 unloaded - 29.937s表示已加载的数量为49052,卸载的数量为39,耗时为29.537s。
  • GC Time:总的(包含新生代和老年代)gc情况记录 123 collections,859.203ms Last Cause:Allocation Failure表示一共经历了123次gc(包含Minor GC和Full GC),总共耗时859.203ms。
  • Eden Space:新生代Eden区内存使用情况 (200.00M,34.125M): 31.52M,109 collections,612.827ms表示Eden区的最大容量为200M,当前容量为34.125M,当前已使用31.52M,从开始监控到现在在该内存区域一共发生了109次gc(Minor GC),gc总耗时为612.827ms。
  • Survivor 0和Survivor 1:新生代的两个Survivor区内存使用情况 (25.000M,4.250M):1.757M表示该Survivor区的最大容量为25M(默认为Eden区的1/8),当前已用1.757M。
  • Old Gen:老年代内存使用情况 (500.000M,255.195M):206.660M,14 collections,246.375ms表示老年区的最大容量为500M,当前容量为255.195M,当前已用206.660M,从开始监控到现在在该内存区域一共发生了14次gc(Full GC),gc总耗时为246.375ms,换算下可以看出单次Full GC要比Minor GC耗时长很多。
  • Metaspace:方法区内存使用情况 (1.053G,278.250M):262.345M表示方法区最大容量为1.053G,当前容量为278.250M,当前使用量为262.345MM。

3.Histogram窗口

Histogram窗口是对当前正在被使用的Survivor区内存使用情况的详细描述,如下:

  • Tenuring

Threshold:我们知道Survivor区中的对象有一套晋升机制,就是其中的每个对象都有一个年龄标记,每当对象在一次Minor GC中存活下来,其年龄就会+1,当对象的年龄大于一个阈值时,就会进入老年代,这个阈值就是Tenuring Threshold,要注意这个值不是固定不变的,一般情况下Tenuring Threshold会与Max Tenuring Threshold大小保持一致,可如果某个时刻Servivor区中相同年龄的所有对象的内存总等于Survivor空间的一半,那Tenuring
Threshold就会等于该年龄,同时大于或等于该年龄的所有对象将进入老年代。

  • Max Tenuring

Threshold:表示新生代中对象的最大年龄值,这个值在JDK1.8中默认为6,在JDK1.7及之前的版本中默认为15,可以通过参数-XX:MaxTenuringThreshold来指定。

  • Desired Survivor Size

Survivor空间大小验证阈值(默认是survivor空间的一半),用于给Tenuring
Threshold判断对象是否提前进入老年代。

  • Current Survivor Size:

当前Survivor空间大小,单位为字节(Byte,B)。

  • Histogram柱状图:

表示Survivor中不同年龄段对象分布。

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

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

相关文章

微信小程序开发之获取用户头像昵称

本文是对另一篇文档 https://blog.csdn.net/duke_ding2/article/details/130674320 的补充。 环境 微信开发者工具 Stable 1.06.2306020调试基础库 2.32.2 背景 在较低版本(2.27.0及以下)的基础库中,在小程序里可以使用 wx.getUserProfil…

PostgreSQL BTree(B-Link-tree) 索引 基本 实现原理

文章目录 背景BTreeBTreeB-Link-Tree 基本数据结构的插入实现BTree Insert 实现BTree Insert 实现 PostgreSQL BTree实现整体结构BTree 索引创建实现_bt_buildadd_bt_uppershutdown BTree 查询 _bt_search 实现BTree 插入 _bt_doinsert 实现_bt_split 节点分裂_bt_insert_paren…

flyway在Windows下安装及基本使用

文章目录 1. flyway中的SQL脚本命名2. flyway执行SQL脚本演示3. flyway中设置 ${CURRENT_DATE} 为当前时间的值 Flyway是一个开源的数据库迁移工具,用于管理和自动化数据库架构的演进。它允许开发人员和团队对数据库进行版本控制,并通过简单的命令行或脚…

【数据库与身份认证】课程笔记

目标: 知道如何配置MySQL数据库环境认识并使用常见的SQL语句操作数据库在Express中操作MySQL数据库了解Session的实现原理了解JWT的实现原理 目录: 数据库的基本概念安装并配置MySQLMySQL的基本使用在Express中操作MySQL前后端的身份认证 一. 数据库的…

美团一面:OOM后,JVM一定会退出吗?为什么?

说在前面 在40岁老架构师 尼恩的读者社区(50)中,最近有小伙伴拿到了一线互联网企业如美团、拼多多、极兔、有赞、希音的面试资格,遇到一几个很重要的面试题: OOM后,JVM一定会退出吗?为什么? 生产环境&am…

MIT 6.S081 (BOOK-RISCV-REV1)教材第四章内容 -- 上

MIT 6.S081 教材第四章内容 -- 上 引言陷阱指令和系统调用RISC-V陷入机制代码:调用系统调用从用户空间陷入系统调用参数补充 引言 MIT 6.S081 2020 操作系统 本文为MIT 6.S081课程第四章教材内容翻译加整理。 本课程前置知识主要涉及: C语言(建议阅读C程序语言设计…

Django基础入门⑤:模板变量和标签的使用

Django基础入门④:数据表显示和Django模板详讲 模板变量使用模板变量模板标签if标签for标签forloop变量forloop.revcounter 示例forloop.first 和 forloop.last 示例forloop.parentloop 示例 🏘️🏘️个人简介:以山河作礼。 &…

Liunx开发工具:git和gdb

目录 一. git的功能和使用 1.1 git的功能 1.2 git三板斧 1.3 git使用中的其他问题 二. 使用gdb调试代码 2.1 生成带有调试信息的可执行程序 2.2 gdb调试代码的方法 一. git的功能和使用 1.1 git的功能 git是一块开源、免费的版本管理系统,能够高效敏捷地处…

【人工智能】— 神经网络、前向传播、反向传播、梯度下降、局部最小值、多层前馈网络、缓解过拟合的策略

【人工智能】— 神经网络、前向传播、反向传播 前向传播反向传播梯度下降局部最小值多层前馈网络表示能力多层前馈网络局限缓解过拟合的策略 前向传播和反向传播都是神经网络训练中常用的重要算法。 前向传播是指将输入数据从输入层开始经过一系列的权重矩阵和激活函数的计算后…

计算机网络408大题(2009-2019)

必备结构 TCP报文段结构 IP数据报结构 2009年 考察点:子网划分、路由表、路由聚合 2010年 考察点:CSMA/CD协议的相关计算 2011年 考察点:以太网帧格式、IP分组格式、IP地址和MAC地址、ARP协议、HTTP/1.1持续的非流水方式 在转发过程中&am…

Jupyter中使用Pyecharts绘制地图

背景:根据各省频率绘制地图 根据各省频率绘制地图,可以使用 Pyecharts 绘制。下面是详细的步骤: 1、安装 Pyecharts:可以通过 !pip install pyecharts 命令安装。 2、导入相关库 import pandas as pd from pyecharts import o…

设计模式之抽象工厂模式笔记

设计模式之抽象工厂模式笔记 说明Abstract Factory(抽象工厂)目录UML抽象工厂示例类图甜品抽象类甜品提拉米苏类甜品抹茶慕斯类 咖啡抽象类美式咖啡类拿铁咖啡类 甜品工厂接口美式风味的甜品工厂意大利风味的甜品工厂 测试类模式扩展 说明 记录下学习设计模式-抽象工厂模式的写…

SSMP整合案例(2) Spring Boot整合Lombok简化实体类开发

好啊 接着我们上文SSMP整合案例(1) 构建 Spring Boot Vue MySql项目环境 我们继续 接下来 我们要在java项目中 建立出数据库表对应的实体类 我们还是先看看自己上文中 创建的这个 book表 其中四个字段 主键id 数字枚举类型的type 字符串类型name 字符串类型 description 我们…

【设计模式与范式:总结型】74 | 总结回顾23种经典设计模式的原理、背后的思想、应用场景等

到今天为止,23 种经典的设计模式已经全部讲完了。咱们整个专栏也完成了 3/4,马上就要进入实战环节了。在进入新模块的学习之前,我照例带你做一下总结回顾。23 种经典设计模式共分为 3 种类型,分别是创建型、结构型和行为型。今天&…

Floyd 判圈算法(Floyd Cycle Detection Algorithm)

Floyd 判圈算法(Floyd Cycle Detection Algorithm) 前言 Floyd判圈算法属于对指针操作的算法,它一般需要且仅需要两个指针,通过设定不同的指针移动速度,来判定链表或有限状态机中是否存在环。人为规定移动较快的指针称为快速指针(fast poin…

Java官方笔记9Lambda表达式

Lambda Expression 有了Lambda Expression,就不用再写anonymous classes。 写Lambda,首先要找到它的类型。 There is a restriction on the type of a lambda expression: it has to be a functional interface. 函数接口,只有1个抽象方法的接…

Vue中v-text、v-html、v-on的基本语法(二)

文章目录 前言一、vue中data属性定义对象、数组相关数据二、v-text、v-html指令使用三、v-on基本指令使用(一)四、v-on指令基本使用(二)之在函数中获取vue实例本身this五、v-on指令基本使用(二)之在函数中传递参数六、v-on指令基本使用(二)之简化写法绑定函数和事件定义的两种写…

从零搭建一台基于ROS的自动驾驶车-----2.运动控制

系列文章目录 北科天绘 16线3维激光雷达开发教程 基于Rplidar二维雷达使用Hector_SLAM算法在ROS中建图 Nvidia Jetson Nano学习笔记–串口通信 Nvidia Jetson Nano学习笔记–使用C语言实现GPIO 输入输出 Autolabor ROS机器人教程 从零搭建一台基于ROS的自动驾驶车-----1.整体介…

Unreal 5 实现丧尸伤害和死亡

这一篇主要是实现玩家攻击丧尸可以造成伤害和自身血量为零时,丧尸可以死亡。丧尸也可以对玩家造成伤害,有攻击范围的判定。 这一篇的功能实现有四个功能: 丧尸被攻击掉血丧尸死亡处理玩家被攻击掉血玩家死亡处理 丧尸被攻击掉血 子弹的修改…

C语言内存操作函数,memcpy的使用和模拟实现,memmove的使用和模拟实现,memcmp的使用,memset的使用。

1.memcpy 函数原型: void *memcpy( void *dest, const void *src, size_t count );void *dest 目标数据首元素地址const void *src 源数据(需要拷贝过去的数据)size_t count 需要拷贝数据的字节大小void *memcpy 拷贝结束后,返回目标数据的起始地址 函…