深入学习JVM(Java虚拟机)

news2024/12/24 3:08:30

目录

一.JDK、JRE、JVM的关系

1.1JDK(Java SE Development Kit)

1.2JRE( Java Runtime Environment)

1.3JVM(Java Virtual Machine)

1.4JDK、JRE、JVM的区别与联系

二.Class的生命周期

2.1加载

2.1.1 类加载器

2.1.2类加载机制

2.1.3双亲委派

2.2链接

2.2.1验证

2.2.2准备

2.2.3解析

2.3初始化

2.4使用

2.5卸载

三.JVM 内存模型

3.1.运行时数据区

四.垃圾回收机制


一.JDK、JRE、JVM的关系

        Java 程序是运行在 JVM(Java 虚拟机)上的,在开发程序之前都要配置 Java 开发环境,其中首先要做的就是 JDK 的安装和配置,那么 JDKJVMJRE 到底有何联系和区别呢?想必并不是每一个程序员都能说得清楚的,接下来将带你了解它们之间的关系。

1.1JDK(Java SE Development Kit)

        Java标准开发工具包,它提供了编译、运行 Java 程序所需的各种工具和资源,包括 Java 编译器、Java 运行时环境,以及常用的 Java 类库等。下图是 JDK 的安装目录:

1.2JRE( Java Runtime Environment)

        Java 运行环境,用于解释执行 Java 的字节码文件。普通用户而只需要安装 JRE就能够Java 程序。而程序开发者必须安装 JDK 来编译、调试程序。下图是 JRE 的安装目录:里面有两个文件夹 bin lib,在这里可以认为 bin 里的就是 jvmlib 中则是 jvm 工作所需要的类库,而 jvm lib 和起来就称为 jre

1.3JVM(Java Virtual Machine)

        JVM,Java 虚拟机,是 JRE 的一部分。它是整个 java 实现跨平台的最核心的部分,负责解释执行字节码文件,是可运行 java 字节码文件的虚拟计算机。所有平台的上的 JVM 向编译器提供相同的接口,而编译器只需要面向虚拟机,生成虚拟机能识别的代码,然后由虚拟机来解释执行。

当使用 Java 编译器编译 Java 程序时,生成的是与平台无关的字节码,这些字节码只面向 JVM。不同平台的 JVM 都是不同的,但它们都提供了相同的接口。JVM 是Java 程序跨平台的关键部分,只要为不同平台实现了相应的虚拟机,编译后的Java 字节码就可以在该平台上运行

1.4JDK、JRE、JVM的区别与联系

1. JDK 用于开发,JRE 用于运行 java 程序 ;如果只是运行 Java 程序,可以只安装 JRE,无需安装 JDK

2. JDK 包含 JREJDK JRE 中都包含 JVM

3. JVM java 编程语言的核心并且具有平台独立性,实现了Java语言的跨平台。

二.Class的生命周期

2.1加载

        java程序经过javac.exe编译成java.class文件存储在磁盘中,而我们的JVM运行在内存中,所以需要将java.class文件通过IO加载到我们的JVM中。这里就设计到类加载器

2.1.1 类加载器

  • 启动类加载器(Bootstrap ClassLoader ):加载$JAVA_HOME 中 jre/lib/rt.jar 里所有的 class 或 Xbootclassoath 选项指定的jar 包! 这些类是 Java 运行的基础类,BootstrapClassLoader 比较特殊,它不继承ClassLoader,而是由 JVM 内部实现;C++实现,并非 java 代码实现

  • 扩展类加载器(Extension ClassLoader):加载 java 平台中扩展功能的一些 jar 包,包括$JAVA_HOME jre/lib/ext/*.jar -Djava.ext.dirs(启动指令属性)指定目录下的 jar 包

  • 系统类加载器(Application ClassLoader):加载 classpath 中指定的 jar 包-Djava.class.path 所指定目录下的类和 jar 包具体实现为 sum.misc.Launcher 中的内部类 AppClassLoader

  • 自定类加载器(Custom ClassLoader):通过继承ClassLoader 实现自己的类加载器,可以通过这种方式打破双亲委派机制。
2.1.2类加载机制
  1.   全盘负责:所谓全盘负责,就是当一个类加载器负责加载某个 Class 时,该Class 所依赖和引用其他 Class 也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入。

  2. 双亲委派:所谓的双亲委派,则是先让父类加载器试图加载该 Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父加载器,依次递归,如果父加载器可以完成类加载任务,就成功返回;只有父加载器无法完成此加载任务时,才自己去加载。

  3. 缓存机制。缓存机制将会保证所有加载过的 Class 都会被缓存,当程序中需要使用某个 Class 时,类加载器先从缓存区中搜寻该 Class,只有当缓存区中不存在该 Class 对象时,系统才会读取该类对应的二进制数据,并将其转换成Class 对象,存入缓冲区中。这就是为很么修改了 Class 后,必须重新启动JVM,程序所做的修改才会生效的原因。   

2.1.3双亲委派

        当一个类收到了类的加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一层的类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载。
        采用双亲委派机制的一个好处是比如加载位于rt.jar包中的类java.lang.Object,不管是哪个加载器加载这个类,最终都是委托顶层的启动类加载器进行加载,这样保证了使用不同的类加载器最终得到的都是同一个Object对象。

好处:

  • 安全,防止了Java的核心API被随意更改
  • 避免了类的重复加载

如何打破双亲委派

        自定义类加载器,继承ClassLoder,重写他的loadCLass方法,不让他向上委派。

2.2链接

        链接分为三步,分别是验证 - > 准备 - > 解析

2.2.1验证

        验证是连接阶段的第一步,这一阶段的目的是为了确保 Class 文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。验证文件格式、元数据、字节码等等

        文件格式验证:此阶段保证输入的字节流能正确地解析并存储于方法区之内,格式上符合描述一个 Java 类型信息的要求。

2.2.2准备

        为静态变量分配内存,赋值初始值

2.2.3解析

        将常量池中的符号引用转为直接引用 解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符 7 类符号引用进行。直接引用就死我们的真实地址。

2.3初始化

        为静态变量赋真正的值。到初始化阶段,才真正开始执行类中定义的 Java 程序代码,此阶段是执行 <clinit>() 方法的过程。

2.4使用

        就是实例化,new一个类的对像。

2.5卸载

Class 被回收要满足以下三个条件:

a) No Instance:该类所有的实例都已经被 GC;

b) No ClassLoader:加载该类的 ClassLoader 实例已经被 GC;

c) No Reference:该类的 java.lang.Class 对象没有被引用。(XXX.class, 静态变量/

)

三.JVM 内存模型

3.1.运行时数据区

方法区:是线程共享的,生命周期和虚拟机一样。存储类信息,静态变量,常量池。方法区满了会OutOfMemoryError(OOM)。

:是线程共享的,生命周期和虚拟机一样。存储的是大部分的对象。堆满了也会OOM.堆是GC的主要空间,堆分为老年代和新生代,新生代又分为eden区S0、S1.

默认    老年代:新生代 = 2:1      Eden :S0 : S1 = 8 : 1 : 1

虚拟机栈:是线程私有的,生命周期和创建的线程一样。存储8种基本数据类型和对象的引用,每调用一个方法就会把一个栈帧压栈。栈满了会报错StackOverflowError。线程太多没有足够的空间创建虚拟机栈就会出现OutOfMemoryError(OOM)。

栈帧包括:局部变量表,操作数栈,动态链接,返回地址

操作数栈是用来执行字节码指令过程中用来计算的。

Java虚拟机栈,执行方法的时候,到底经历什么? javap 反编译->字节码指令,对应Java虚拟机栈执行过程

本地方法栈:线程私有的,调用nativ方法的。结构与虚拟机栈相似。

程序计数器:线程私有的,记录程序执行到第几行。他是唯一不会内存溢出的

四.垃圾回收机制

Java垃圾回收机制(GC)

五.JVM参数

1.1标准参数

不会随着 JDK 版本的变化而变化

-version

-help

-server

-cp

1.2-X参数

非标准参数,也就是在 JDK 各个版本中可能会变动

java -Xint -version 解释执行

java -Xcomp -version 第一次使用就编译成本地代码

java -Xmixed -version 混合模式,JVM 自己来决定

1.3-XX参数

使用得最多的参数类型非标准化参数,相对不稳定,主要用于 JVM 调优和 Debug。

a.Boolean 类型

格式:-XX:[+-]<name>                              +或-表示启用或者禁用 name 属性

比如:-XX:+UseConcMarkSweepGC       表示启用 CMS 类型的垃圾回收器

           -XX:+UseG1GC                             表示启用 G1 类型的垃圾回收器

b.Boolean 类型

格式:-XX:<name>=<value>                    表示 name 属性的值是 value

比如:-XX:MaxGCPauseMillis=500

          -XX:InitialHeapSize=100M              表示初始化堆大小为100M

1.4其他参数

-Xms100M         等价于-XX:InitialHeapSize=100M

-Xmx100M         等价于-XX:MaxHeapSize=100M

-Xss100k           等价于-XX:ThreadStackSize=100k

java -XX:+PrintFlagsFinal -version       查看参数

1.5五大常用参数

jps  查看java进程

jinfo  实时查看和调整 JVM 配置参数

  • 查看:jinfo -flag name PID 查看某个 java 进程的 name 属性的值。  例如:jinfo -flag MaxHeapSize PID
  • 修改:参数只有被标记为 manageable flags 可以被实时修改。 jinfo -flag name=value PID。例如: jinfo -flag MaxHeapSize = 20M PID

jstat  查看性能

jstack  查看栈

jmap 查看堆

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof  这个参数可以在OOM时自动打印dump文件

jmap -dump:format=b,file=heap.hprof pid  手动打印dump

打印出来的dump文件可以结合工具来分析

1.6调优思路

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

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

相关文章

antd-vue 级联选择器默认值不生效解决方案

一、业务场景&#xff1a; 最近在使用Vue框架和antd-vue组件库的时候&#xff0c;发现在做编辑回显时** 级联选择器** 组件的默认值不生效。为了大家后面遇到和我一样的问题&#xff0c;给大家分享一下 二、bug信息&#xff1a; 三、问题原因&#xff1a; 确定不了唯一的值&a…

GEE:根据影像最小值和最大值自适应可视化参数设置

作者:CSDN @ _养乐多_ 本文将介绍根据影像最小值和最大值,自适应的设置影像可视化参数设置。 文章目录 一、核心函数二、代码示例三、代码链接一、核心函数 //计算影像的最小值和最大值,为了可视化 var imageMin = (image.reduceRegion({reduc

使用CRM管理销售渠道的 5 个重要优势

销售渠道的管理是创造积极客户体验的关键因素&#xff0c;对企业来说非常重要。大多数情况下&#xff0c;客户关系管理&#xff08;CRM&#xff09;系统可用于高效的销售渠道管理。那么&#xff0c;利用CRM系统管理销售渠道有哪些优势呢&#xff1f; 1) 有效的线索管理 销售渠…

CSS实现鼠标悬停图片上升显示

文章目录 前言一、实现效果二、实现思路 前言 当我们想在图片上面放置一些文字内容时&#xff0c;发现不管怎么放置&#xff0c;要么就是图片影响到文字的观感&#xff0c;要么就是文字挡住图片的细节&#xff0c;那么怎么可以既看到图片的细节又可以看到对图片的文字描述呢&a…

基于R语言分位数回归丨线性回归假设与分位数函数、线性分位数回归 、贝叶斯分位数回归、超越线性分位数回归等

目录 专题一 线性回归假设与分位数函数讲解 专题二 线性分位数回归 【代码实践】 专题三 贝叶斯分位数回归【代码实践】 专题四 超越线性分位数回归&#xff08;一&#xff09;【代码实践】 专题五 超越线性分位数回归&#xff08;二&#xff09;【代码实践】 更多应用 回…

怎样的外发文件管理办法 能够避免数据外发泄露?

在日常办公中&#xff0c;重要文件保密管理可谓“老生常谈”。但我们往往容易忽视&#xff0c;文件保密管理并非个体所能独立完成&#xff0c;在整个文件运转过程中&#xff0c;存在多名经手人&#xff0c;一人发生疏忽&#xff0c;则整个安全屏障都会被打破。 因此&#xff0c…

膝盖前交叉韧带断裂

等级、治愈&#xff08;几乎不可能&#xff0c;除非康复阶段做得非常到位。手术后可恢复到90%&#xff09;&#xff0c;饮食&#xff0c;康复训练&#xff08;完全康复&#xff09;、心理作用 赔偿&#xff1a;工商&#xff08;分出两份&#xff09;&#xff0c;伤残证&#x…

Spring Boot 如何实现单点登录(SSO)

当今的应用程序越来越多地采用了微服务架构&#xff0c;这就引出了一个重要的问题&#xff1a;如何实现单点登录&#xff08;Single Sign-On&#xff0c;简称SSO&#xff09;来确保用户在多个微服务之间无需重复登录。Spring Boot是一个流行的Java框架&#xff0c;它提供了一些…

旅行季《乡村振兴战略下传统村落文化旅游设计》许少辉八一新著作想象和世界一样宽广

旅行季《乡村振兴战略下传统村落文化旅游设计》许少辉八一新著作想象和世界一样宽广

AB试验(四)基于规范流程的一个案例分析

AB试验&#xff08;四&#xff09;基于规范流程的一个案例分析 确定目标和假设 业务场景&#xff1a;某音乐APP&#xff0c;通过历史数据发现一些便利功能往往有着较高的留存和续订。但是这些便利功能的使用率并不高。调研发现&#xff0c;由于APP崇尚简洁设计&#xff0c;因…

排序算法二 归并排序和快速排序

目录 归并排序 快速排序 1 挖坑法​编辑 2 Hoare法 快排的优化 快排的非递归方法 七大排序算法复杂度及稳定性分析 归并排序 归并排序是建立在归并操作上的一种有效的排序算法,将以有序的子序列合并,得到完全有序的序列,即先使每个子序列有序,在使子序列段间有序.若将两…

李沐_动手学深度学习_19_卷积层

一、遇到的磕磕绊绊&#xff1a; 1.一维数组 和 二维矩阵数据之间的区别&#xff1a; 二、用到的一些代码&#xff1a; #备注&#xff0c;矩阵点乘 就是 A*B import torch from d2l import torch as d2l #这个库是李沐自己写的&#xff0c;我去 from torch import nndef co…

【React】JSX语法

目录 一、前言二、JSX介绍三、JSX原理1、DOM结构示例2、HTML的JSX结构示例3、编译之后的代码 四、为什么使用JSX1、JSX的特点2、JSX的书写规范 五、JSX的使用1、嵌入JS表达式2、条件渲染3、列表渲染①、arr.map() 六、组件1、类组件①、实例化组件 2、函数组件3、组件样式①、行…

无缝转换:将File转化为MultipartFile,轻松应对文件上传

无缝转换&#xff1a;将File转化为MultipartFile&#xff0c;轻松应对文件上传 1、概述2、文件转换2.1、 什么是 MultipartFile2.2、将 File 对象转换为 MultipartFile 对象 3、总结 1、概述 大家好&#xff0c;我是欧阳方超&#xff0c;可以关注我的公众号“欧阳方超”&#…

Linux 搭建 Oracel 10g 环境

Oracle 操作 1. Linux 安装 oracle 10g (1) 登录系统 操作系统: Kylin 3.2 硬盘空间: 8G 以上 数据库版本: oracle 10.2.0 使用 root 用户登录操作系统&#xff0c;若为普通用户使用su命令切换至 root用户。 (2) 准备文件 将数据库安装文件&#xff08;10201_database_…

字节8年经验之谈 —— 10大自动化测试框架总结!

软件行业正迈向自主、快速、高效的未来。为了跟上这个高速前进的生态系统的步伐&#xff0c;必须加快应用程序的交付时间&#xff0c;但不能以牺牲质量为代价。快速实现质量是必要的&#xff0c;因此质量保证得到了很多关注。为了满足卓越的质量和更快的上市时间的需求&#xf…

LL库实现正交编码器数据采集

1&#xff0c;首先打开STM32CubeMX&#xff0c;配置一下工程&#xff0c;这里使用的芯片是STM32F103C8T6。 我这里选择了定时器2和3&#xff0c;因为我有两个电机&#xff0c;在定时器模式这边&#xff0c;我们在Combined Channels这个选项里面我们选择Encoder Mode&#xff0c…

IDEA远程调试Remote Debug

配置idea远程调试 输入服务器ip&#xff0c;并且复制启动参数&#xff1a; -agentlib:jdwptransportdt_socket,servery,suspendn,address5005 使用IDEA远程调试自动生成的参数启动服务器 java -Xdebug -agentlib:jdwptransportdt_socket,servery,suspendn,address5005 -jar …

Java on Azure Tooling 8月更新|以应用程序为中心的视图支持及 Azure 应用服务部署状态改进

作者&#xff1a;Jialuo Gan - Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎阅读 Java on Azure 工具的八月更新。在本次更新中&#xff0c;我们将推出新的以应用程序为中心的视图支持&#xff0c;帮助开发人员在一个项…

LVS+Keepalived:实现高效软负载均衡的利器

一、概念 LVS是Linux Virtual Server的简写&#xff0c;意即Linux虚拟服务器&#xff0c;是一个虚拟的服务器集群系统&#xff0c;它可以通过不同的调度算法和工作模式&#xff0c;将客户端的请求转发给后端的真实服务器。 Keepalived是一个基于VRRP协议来实现的服务高可用方案…