简述JVM(1)——类加载器和运行时数据区(上)

简介: 简述JVM(1)——类加载器和运行时数据区(上)

了解JVM(Java虚拟机)首先我们必须了解VM(虚拟机)是什么。


所谓虚拟机(Virtual Machine),就是一台虚拟的计算机。它是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。


我们经常见到的 VMware 就属于系统虚拟机,它是完全对物理计算机的仿真,提供了一个可运行完整操作系统的软件平台。


程序虚拟机典型的代表就是 Java 虚拟机了,它专门为执行某个单个计算机程序而设计。在 Java 虚拟机中执行的指令我们称为 Java 字节码指令。无论是系统虚拟机还是程序虚拟机,在上面运行的软件都被限制于虚拟机提供的资源。Java 虚拟机是一种执行 Java 字节码文件的虚拟计算机,它拥有独立的运行机制。


Java 技术的核心就是 Java 虚拟机,因为所有的 Java 程序都运行在 Java 虚拟机内部。


JVM概述


JVM就是Java虚拟机,虚拟机就是一台虚拟的计算机,是一款软件。Java 虚拟机就是二进制字节码的运行环境,负责装载字节码到其内部,解释或编译为对应平台上的机器码指令执行,每一条 Java 指令,Java 虚拟机中都有详细定义,如怎么取操作数,怎么处理操作数,处理结果放在哪儿等。JVM是运行在操作系统上的,不与硬件直接交互。


JVM整体的四个部分


JVM整体组成可以分为4个部分:

1.类加载器(ClassLoader)

2.运行时数据区(Runtime Data Area)

3.执行引擎(Execution Engine)

4.本地方法接口(Native Interface)


程序在执行之前先要把 Java 代码转换成字节码(.class 文件),JVM 首先需要把字节码通过一定的类加载器(Class Loader)把文件加载到内存中运行时数据区(Runtime Data Area),而字节码文件是 JVM 的一套指令集规范,并不能直接交给底层操作系统去执行,因此需要特定的命令解析器(执行引擎(Execution Engine)) 将字节码翻译成底层系统指令再交由 CPU 去执行,而这个过程中需要调用其他语言的接口(本地方法接口(Native Interface)) 来实现。整个程序的功能,这就是这 4 个主要组成部分的职责与功能。


1.1 类加载器

Java编译器会为虚拟机转换源指令。虚拟机代码存储在以 .class 为扩展名的类文件中,每个类文件都包含某个类或者接口的定义和实现代码。 ——Java核心基础(卷二)


1.1.1 类加载器过程

类加载器子系统负责从文件系统或者网络中加载 class 文件, class 文件在文件开头有特定的文件标识(字节码文件都以 CA FE BA BE 标识开头)。classLoader 只负责 class 文件的加载,至于它是否可以运行,则由执行引擎决定。加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是 class 文件中常量池部分的内存映射)。


类加载的过程

image.png



1.加载过程是把class文件(字节码文件)加载到内存中(I/O读写)。类加载器把文件加载到内存中,会为每个类创建一个Class类的对象,调用Class类中的方法获取类的相关信息。

2.验证是检验加载的类是否有正确的内部结构并和其他类协调一致。

3.准备阶段为类的静态属性分配内存,并设置默认初始值(不包含final修饰的static常量),也不会给实例变量初始化。

4.解析是将二进制数据中的符号引用替换成直接引用(符号引用是用一组符号描述所引用的目标;直接引用是指向目标的指针)。

5.类初始化


5.1 什么时候初始化类

1 )创建类的实例,也就是 new 一个对象

2)访问某个类或接口的静态变量,或者对该静态变量赋值

3)调用类的静态方法

4)反射

5)初始化一个类的子类(会首先初始化子类的父类)


5.2 类的初始化顺序:

父类static --> 子类static --> 父类构造方法 --> 子类构造方法

1.1.2类加载器的分类

1.1.2.1启动类加载器(引导类加载器)

是由c/c++实现,用来加载Java的核心类库

1.1.2.2扩展类加载器

由Java实现,派生于 ClassLoader 类。上层类加载器是引导类加载器(启动类加载器),加载底层类库

1.1.2.3应用程序类加载器

Java实现,派生于 ClassLoader 类。上层类加载器是扩展类加载器,加载自定义类。


1.1.3 双亲委派机制

加载类时,向上委派,交给最上层的加载器启动类加载器加载核心类库,加载不到就用扩展类加载器加载底层类库,加载不到就用应用程序类加载器加载自定义类


双亲委派机制的优点

1.安全,可避免用户自己编写的类动态替换 Java 的核心类(自定义的类名和Java核心类名相同)

2.避免全限定命名的类重复加载(使用了 findLoadClass()判断当前类是否已加载)


1.1.4沙箱安全机制

作用是防止恶意代码污染 Java 源代码

如果一个类在引导类加载器那里就加载到了,先找到先使用,所以就使用引导类加载器里面的类,后面的一概不能使用,这就保证了不被恶意代码污染。


1.1.5 类的主动使用和被动使用

JVM 规定,每个类或者接口被首次主动使用时才对其进行初始化,有主动使用,自然就有被动使用。


主动使用:

1.通过new关键字被导致类的初始化,这是大家经常使用的初始化一个类的方式,

他肯定会导致类的加载并且初始化

2.访问类的静态变量,包括读取和更新

3.访问类的静态方法

4.对某个类进行反射操作,会导致类的初始化

5.初始化子类会导致父类的的初始化

6.执行该类的 main 函数


被动使用:其实除了上面的几种主动使用其余就是被动使用了


注意:主动使用和被动使用的区别在于类是否会被初始化.

1.引用该类的静态常量,注意是常量,不会导致初始化,但是也有意外,这里的常量是指已经指定字面量的常量,对于那些需要一些计算才能得出结果的常量就会导致初始化,比如:

public final static int number = 5 ; //不会导致类初始化,被动使用

public final static int random = new Random().nextInt() ; //会导致类的初始化,主动使用

2.构造某个类的数组时不会导致该类的初始化,比如:

Student[] students = new Student[10] ;


目录
相关文章
|
12月前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
964 55
|
12月前
|
Arthas Java 测试技术
JVM深入原理(六)(一):JVM类加载器
目录6. JVM类加载器6.1. 类加载器-概述6.2. 类加载器-执行流程6.3. 类加载器-分类(JDK8)6.3.1. JVM底层实现的类加载器6.3.1.1. 启动类加载器6.3.2. Java代码实现类的加载器6.3.2.1. 扩展类加载器6.3.2.2. 应用程序类加载器6.4. 类加载器-Arthas查看类加载器
222 0
|
12月前
|
存储 安全 Java
JVM深入原理(七)(一):运行时数据区
栈的介绍:Java虚拟机栈采用栈的数据结构来管理方法调用中的基本数据,先进后出,每一个方法的调用使用一个栈帧来保存栈的组成:栈:一个线程运行所需要的内存空间,一个栈由多个栈帧组成栈帧:一个方法运行所需要的内存空间活动栈帧:一个线程中只能有一个活动栈帧栈的生命周期:栈随着线程的创建而创建,而回收会在线程销毁时进行栈的执行流程:栈帧压入栈内执行方法执行完毕释放内存若方法间存在调用,那么会压入被调用方法入栈,执行完后释放内存,再执行当前方法,直到执行完毕,释放所有内存。
242 0
|
12月前
|
存储 缓存 安全
JVM深入原理(七)(二):运行时数据区
堆的作用:存放对象的内存空间,它是空间最大的一块内存区域.栈上的局部变量表中,可以存放堆上对象的引用。静态变量也可以存放堆对象的引用,通过静态变量就可以实现对象在线程之间共享。堆的特点:线程共享:堆中的对象都需要考虑线程安全的问题垃圾回收:堆有垃圾回收机制,不再引用的对象就会被回收方法区的概述:方法区是存放基础信息的位置,线程共享,主要包括:类的元信息:保存了所有类的基本信息运行时常量池:保存了字节码文件中的常量池内容静态常量池:字节码文件通过编号查表的方式找到常量。
178 0
|
存储 Java C++
JVM 运行时数据区
Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存区域划分为若干个不同的数据区域。这 些区域都有各自的用途,以及创建和销毁的时间,有些区域随着虚拟机进程的启动而存在,有些区 域则是依赖线程的启动和结束而建立和销毁。Java 虚拟机所管理的内存被划分为如下几个区域 程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解 析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳 转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成; 为什么要线程计数器?因为线程是不具备记忆功能 Java 虚拟机
|
Java
JVM运行时数据区
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一
172 2
|
Java
JVM运行时数据区(内存结构)
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一 (3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码
208 3
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
1732 3
|
Arthas 监控 Java
Arthas memory(查看 JVM 内存信息)
Arthas memory(查看 JVM 内存信息)
960 6
|
7月前
|
存储 缓存 Java
我们来说一说 JVM 的内存模型
我是小假 期待与你的下一次相遇 ~
508 5