【Java虚拟机】JVM核心基础和常见参数实战

news2024/11/28 2:37:00

1.新版JVM内存组成部分和堆空间分布

JVM内存的5大组成(基于JDK8的HotSpot虚拟机,不同虚拟机不同版本会有不一样)

名称作用特点
程序计数器也叫PC寄存器,用于记录当前线程执行的字节码指令位置,以便线程在恢复执行时能够从正确的位置开始线程私有
Java虚拟机栈用于存储Java方法执行过程中的局部变量、方法参数和返回值,以及方法执行时的操作数栈线程私有
本地方法栈用于存储Java程序调用本地方法的参数和返回值等信息。线程私有
用于存储Java程序创建的对象,所有线程共享一个堆,堆中的对象可以被垃圾回收器回收,以便为新的对象分配空间线程共享
元数据区用于存储类的元数据信息,如类名、方法名、字段名等,以及动态生成的代理类、动态生成的字节码等
元空间是位于本地(直接)内存中的,而不是像JDK8之前方法区位于堆内存中的。
线程共享

在这里插入图片描述

堆空间内存分布

  • 用于存储Java程序创建的对象,所有线程共享一个堆
  • 堆中的对象可以被垃圾回收器回收,以便为新的对象分配空间

在这里插入图片描述

2.JVM堆空间垃圾回收流程

(1)面试题:说下JVM里面堆内存划分和堆内存垃圾回收流程

  • 新建对象,放到Eden区,满后触发Minor GC(每次都是由Eden区满触发Minor GC,接连放对象到S0或S1)
  • 存活的对象移动到Survivor的S0区,如果S0满后触发Minor GC
  • S0存活下来的对象移动到S1区,然后S0区空闲
  • S1满后触发Minor GC,再次移动到S0区,然后S1区空闲
  • 反复GC每次对象涨1岁,到达一定次数后(默认15),进入老年代
  • 当老年代内存不足会触发Full GC,出现STW(Stop-The-World)
  • 堆被垃圾回收,基本都是采用分代收集算法,不通区域的采用不同的垃圾回收算法
  • 方法结束后,堆中的对象不会马上移除,在垃圾回收的时候才会被移除

(2)面试题:堆空间里面分配比例如何

在这里插入图片描述

官方推荐一般老年代与新生代的占比为2:1,即老年代占整个堆空间的2/3,新生代占整个堆空间的1/3,在Yong区又分三个区域 Eden、Survivor-0、Survivor-1,Eden分整个Yong的8/10,两个Survivor各占1/10。

3.JVM内存垃圾回收相关参数

(1)JVM参数格式分类

格式解释例子
标准参数(-)所有JVM都实现这些参数的功能-verbose:gc 打印GC简要信息
非标准参数(-X)不保证所有JVM实现都满足-Xmx2048m等价 -XX:MaxHeapSize JVM最大堆内存为2048M
非稳定参数(-XX)不稳定未来可能取消,但很有用-XX:+PrintGCDetails每次GC时打印详细信息。
-XX:+开启对应的参数-XX:+PrintGCDetails 开启每次GC时打印详细信息。
-XX:-关闭对应的参数-XX:-DisableExplicitGC 禁止调用System.gc()
-XX:=设定数字参数-XX:NewRatio=2 新生代和老年代内存比例

(2)JVM堆栈内存配置参数

参数解释
-Xms初始堆大小,推荐和最大堆一样
-Xmx最大堆大小,推荐和初始堆一样
-Xmn年轻代大小
-Xss每个线程的栈大小

(3)JVM常见的命令行参数配置

参数解释
-XX:+PrintGCDetails打印GC回收信息
-XX:NewRatio新生代和老年代空间大小的比率,由-XX:NewRatio参数控制
-XX:NewRatio参数的默认值是2,表示新生代和老年代的比例是1:2
如果将-XX:NewRatio设置为4,表示新生代和老年代的比例是1:4
-XX:MaxMetaspaceSize元空间所分配内存的最大值,默认没限制
-XX:+UseConcMarkSweepGC设置并发收集器

4.JVM虚拟机栈参数调整案例实战

JVM虚拟机栈

  • 用来存储Java程序中的方法调用和局部变量的内存区域
  • 每个线程都有自己的虚拟机栈,其生命周期与线程相同
  • 当一个方法被调用时,Java虚拟机会在该线程的虚拟机栈中创建一个栈帧,用来存储该方法的局部变量、方法返回值等信息
  • 异常情况
    • 默认情况下,JVM虚拟机栈的大小是固定的,JDK1.5后通常为1MB
    • 如果线程在执行方法时需要更多的栈空间,JVM会抛出StackOverflowError异常
    • JVM参数 xss,比如 -Xss1m 表示1MB

(1)案例:模拟递归调用,对count一直++,直到栈溢出

public class StackFrameDemo {

    private static int count = 0;
    
    public static void main(String[] args) {
        try {
            recursiveMethod();
        } catch (Throwable t) {
            System.out.println("Stack overflow after " + count + " invocations.");
            t.printStackTrace();
        }
    }

    private static void recursiveMethod() {
        count++;
        recursiveMethod();
    }

}
  • 配置栈大小,最少208k,低于208k启动不起来项目,我们这块配置 524k,-Xss524k

在这里插入图片描述

  • 再次测试

在这里插入图片描述

  • 结论:

    • 栈越小,递归调用的次数就越少,因为栈空间不足导致栈溢出异常

    • 栈越大,递归调用的次数就越多,因为有足够的栈空间来存储方法调用的信息

5.JVM堆参数调整压测案例实战

  • 需求
    • 通过调整不同的JVM堆参数,查看相关指标
  • 测试接口
@RestController
@RequestMapping("api/v1/data")
public class DataController {

    @RequestMapping("compute")
    public String compute() {
        Byte[] b = new Byte[1024*1024];
        return "success";
    }
}
  • JVM参数
  • 调整参数一

    • 参数 -Xms64m -Xmx64m
    • 性能指标

在这里插入图片描述

  • 调整参数二

    • 参数 -Xms640m -Xmx640m

    • 性能指标

在这里插入图片描述

6.JDK8之后的方法区实现和元空间的联系

(1)什么是方法区和元空间

  • 【方法区】是JVM中用来存储类的元数据信息的区域,包括类的结构、方法、字段信息等,Java堆类似各个线程共享的内存区域

  • 元空间、永久代是方法区具体的落地实现

    • java8之前是称为永久代(PermGen),java8后引入的一个新概念【元空间】用于替代旧版JVM中的永久代(PermGen)

      • 方法区和永久代以及元空间的关系很像 Java 中接口和类的关系
      • 类实现了接口,类就可以看作是永久代和元空间,接口可以看作是方法区
      • 永久代是 JDK 1.8 之前的方法区实现,JDK 1.8 及以后方法区的实现便成为元空间

在这里插入图片描述

  • 元空间的大小是动态的,可以根据需要进行自动扩展,如果元空间不足,JVM会抛出 OutOfMemoryError : Metaspace

  • 元空间大小配置

    • -XX:MetaspaceSize

      • 用来设置元空间初始大小的参数,它的默认值是21 MB
    • -XX:MaxMetaspaceSize

      • 用来设置元空间最大大小的参数,它的默认值是-1 即不限制,使用的是本地内存,不像旧版的永久代是堆内存
      • 如果不限制元空间的大小,可能会导致元空间占用过多的内存,从而引起内存溢出
    • 系统参数查看

      • 这两个参数的单位是字节(B),可以使用K、M、G等后缀来表示更大的单位
public class HeapDemo {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("测试元空间进程");
        Thread.sleep(10000000);
    }
}
  • 查看命令
jps #查看进程号
jinfo -flag MetaspaceSize 进程号  #查看Metaspace分配内存空间 
jinfo -flag MaxMetaspaceSize 进程号 #查看Metaspace最大空间

在这里插入图片描述

  • 调整
-XX:MetaspaceSize=126m -XX:MaxMetaspaceSize=524m

在这里插入图片描述

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

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

相关文章

常见的DNS攻击与相应的防御措施

DNS查询通常都是基于UDP的,这就导致了在查询过程中验证机制的缺失,黑客很容易利用该漏洞进行分析。DNS服务可能面临如下DNS攻击风险: 黑客伪造客户端源IP地址发送大量的DNS请求报文,造成DNS request flood攻击。 黑客伪造成授权服…

MongoDB实现---存储机制

储存 GridFS机制 GridFS:将大文件分隔成多个小文档存放,这样我们能够有效的保存大文档,而且解决了BSON对象有限制的问题;通过两个集合实现:两个集合分别存储存储实际数据和存储文件的元数据: 元数据文件&…

一篇文章搞定《动手学深度学习》-(李沐)PyTorch版本的所有内容

目录 目录 简介 阅读指南 1. 深度学习简介 2. 预备知识 3. 深度学习基础 4. 深度学习计算 5. 卷积神经网络 6. 循环神经网络 7. 优化算法 8. 计算性能 9. 计算机视觉 10. 自然语言处理 环境 参考(大家可以在这里下载代码) 原书地址&#…

四结(4.13)多线程学习

今天又进行了一次学长授课,关于MySQL和JDBC本来学了增删查改操作,用IDEA也可以操作数据库,今天讲了一些数据库的规范(三大范式)、以及er图。了解了一下项目。 项目要分为客户端和服务端(C/S)来写…

vue面试题2023

1.$route和$router的区别? routes : 数组。 路由匹配规则 router : 对象。 路由对象 $router : 对象。 用于跳转路由 和 传递参数 $route :对象。 用于接收路由跳转参数 1.Vue的生命周期方法有哪些? - beforeCreate 初始化实…

科技云报道:“云减碳”成趋势,如何用“计算”帮助企业碳减排?

科技云报道原创。 将数据中心“丢进”水里、“扔进”山里,使用风能、太阳能等清洁能源为数据中心供电……这些都是通过物理方法为数据中心减碳。 数据中心的重要工作在于计算,计算导致了能源消耗,使其成为耗能大户,而通过云计算…

基于imx8m plus开发板全体系开发教程1:Windows/Linux 开发环境配置(连载中)

前言: i.MX8M Plus 开发板是一款拥有 4 个 Cortex-A53 核心,运行频率 1.8GHz;1 个 Cortex-M7 核心,运行频率 800MHz;此外还集成了一个 2.3 TOPS 的 NPU,大大加速机器学习推理。 全文所使用的开发平台均为与NXP官方合作的FS-IMX8…

Terraform 系列-什么是 IaC?

系列文章 👉 Terraform 系列文章 前言 聊到 Terraform, 必然绕不开 IaC 这个概念?那么,什么是 IaC? 🤔 基本概念 基础架构即代码 (Infrastructure as Code, IaC) 是指通过代码而不是手动流程/控制台点击来管理和配置基础架构…

互联网+制造业:图扑数字孪生智慧工厂车间生产线

前言 随着信息技术、自动化技术和人工智能等技术的快速发展和应用,智能制造已成为全球制造业发展的主流趋势。智能制造是将智能化、自动化、数字化和网络化等技术手段运用到制造过程中,使生产过程具有高度智能化、自动化和数字化的特点,进而…

Linux安装宝塔,并实现公网远程登录宝塔面板【内网穿透】

文章目录前言1. 安装宝塔2. 安装cpolar内网穿透3. 远程访问宝塔4. 固定http地址5. 配置二级子域名6. 测试访问二级子域名转发自CSDN远程穿透的文章:Linux安装宝塔,并实现公网远程登录宝塔面板【内网穿透】 前言 宝塔面板作为建站运维工具,它…

网络编程2(套接字编程)

套接字编程UDP协议通信:TCP通信:套接字编程:如何编写一个网络通信程序 1.网络通信的数据中都会包含一个完整的五元组: sip,sport,dip,dport,protocol(源IP,源…

计算机组成原理——第三章存储系统(上)

提示:吾与春风皆过客,君携秋水揽星河 文章目录前言3.1 存储系统基本概念3.2.1 主存储器的基本组成3.2.2 SRAM DRAM\3.2.3 只读存储器ROM3.3.1 主存储器与CPU的连接3.3.2 双端口RAM和多模块存储器前言 提示:以下是本篇文章正文内容&#xff0c…

带你理解运算放大器

复习一下电子设计基本元器件,运算放大器 ...... 矜辰所致目录前言一、运放基本说明1.1 基本认识1.2 运放中的电流1.3 运放工作特性二、负反馈2.1 什么是负反馈?2.2 为什么要引入负反馈?负反馈电路分析2.3 正反馈三、提一下虚短与虚断结语前…

MAX14808 八通道3级电平 数字脉冲发生器

MAX14808八通道3级电平 高压(HV) 脉冲发生器,利用低压控制逻辑输入产生高频、高压双极性脉冲(高达105V) ,用于驱动超声系统的压电传感器,MAX14808有八个集成的发送/接收(T/R)开关。 应用 超声医疗成像工业探伤检测压电驱动器测试设备 芯片…

RocketMQ 是是如何管理消费进度的?又是如何保证消息成功消费的?

RocketMQ 消费者保障 作者: 博学谷狂野架构师GitHub:GitHub 地址 (有我精心准备的 130 本电子书 PDF)只分享干货、不吹水,让我们一起加油!😄 消息确认机制 consumer 的每个实例是靠队列分配来决定如何消费消…

五、MyBatis各种查询功能

MyBatis的各种查询功能 如果查询出的数据只有一条,可以通过 实体类对象接收List集合接收Map集合接收 如果查询出的数据有多条,一定不能用实体对象接收,会抛TooManyResultsException,可以通过 实体类类型的List集合接收Map类型的L…

Python爬虫自动化从入门到精通第10天(Scrapy框架的基本使用)

Scrapy框架的基本使用Scrapy框架简介Scrapy框架的运作流程安装Scrapy框架Scrapy框架的基本操作Scrapy常用命令Scrapy框架简介 Scrapy框架主要包含以下组件: Scrapy Engine(引擎):负责Spiders、Item Pipeline、Downloader、Scheduler之间的通信&#xf…

手把手教你安装Visual Studio 2019(史上最全)

前言: 本文是以Visual Studio Community 2019为例子,介绍如何在微软官网下载Visual Studio Community 2019并安装.net桌面开发程序环境(主要是winform开发环境)。 下载请点击这里Visual Studio Community 2019下载,然后点击下图的箭头的DownLoad下载,要注意的是下载时要…

微信自定义菜单

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目…

全链路压测时动态路由数据源MySQL、MongoDB、Redis

目录 一、全链路压测 二、动态路由Mysql 1. 参数配置application-localDynamic.yml 2. 加载配置参数DynamicDataSourceProperties.java 3. 动态数据源DynamicDataSource.java 4. 动态数据源供应DynamicDataSourceProvider.java 5. 动态数据源bean 6. 动态数据源上下文D…