简述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] ;


目录
相关文章
|
10天前
|
监控 算法 Java
Java虚拟机(JVM)使用多种垃圾回收算法来管理内存,以确保程序运行时不会因为内存不足而崩溃。
【6月更文挑战第20天】Java JVM运用多种GC算法,如标记-清除、复制、标记-压缩、分代收集、增量收集、并行收集和并发标记,以自动化内存管理,防止因内存耗尽导致的程序崩溃。这些算法各有优劣,适应不同的性能和资源需求。垃圾回收旨在避免手动内存管理,简化编程。当遇到内存泄漏,可以借助VisualVM、JConsole或MAT等工具监测内存、生成堆转储,分析引用链并定位泄漏源,从而解决问题。
22 4
|
12天前
|
算法 Java
Java垃圾回收(Garbage Collection,GC)是Java虚拟机(JVM)的一种自动内存管理机制,用于在运行时自动回收不再使用的对象所占的内存空间
【6月更文挑战第18天】Java的GC自动回收内存,包括标记清除(产生碎片)、复制(效率低)、标记整理(兼顾连续性与效率)和分代收集(区分新生代和老年代,用不同算法优化)等策略。现代JVM通常采用分代收集,以平衡性能和内存利用率。
36 3
|
17天前
|
存储 缓存 安全
JVM(三)-运行时数据区(栈、程序计数器)
JVM(三)-运行时数据区(栈、程序计数器)
13 2
|
2天前
|
安全 前端开发 Java
《JVM由浅入深学习【一】 》JVM由简入深学习提升(类加载过程+父子类加载过程+类加载器+双亲委派机制)
《JVM由浅入深学习【一】 》JVM由简入深学习提升(类加载过程+父子类加载过程+类加载器+双亲委派机制)
7 0
|
26天前
|
存储 Java 编译器
【JavaEE初阶】 JVM 运行时数据区简介
【JavaEE初阶】 JVM 运行时数据区简介
|
6天前
|
存储 Java C++
Java虚拟机(JVM)在执行Java程序时,会将其管理的内存划分为几个不同的区域
【6月更文挑战第24天】Java JVM管理内存分7区:程序计数器记录线程执行位置;虚拟机栈处理方法调用,每个线程有独立栈;本地方法栈服务native方法;Java堆存储所有对象实例,垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息;运行时常量池存储常量;直接内存不属于JVM规范,通过`java.nio`手动管理,不受GC直接影响。
16 5
|
4天前
|
存储 Java 对象存储
jvm内存模型剖析
当线程cpu时间片执行完后,线程进入休眠状态,当再次唤醒时,通过程序计数器确定指令执行到哪一行,然后继续往下执行。
16 1
|
6天前
|
存储 Java C++
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据
Java虚拟机(JVM)管理内存划分为多个区域:程序计数器记录线程执行位置;虚拟机栈存储线程私有数据,如局部变量和操作数;本地方法栈支持native方法;堆存放所有线程的对象实例,由垃圾回收管理;方法区(在Java 8后变为元空间)存储类信息和常量;运行时常量池是方法区一部分,保存符号引用和常量;直接内存非JVM规范定义,手动管理,通过Buffer类使用。Java 8后,永久代被元空间取代,G1成为默认GC。
17 2
|
17天前
|
算法 安全 Java
JVM系列4-垃圾收集器与内存分配策略(二)
JVM系列4-垃圾收集器与内存分配策略(二)
23 0
JVM系列4-垃圾收集器与内存分配策略(二)
|
2天前
|
缓存 Java
《JVM由浅入深学习九】 2024-01-15》JVM由简入深学习提升分(生产项目内存飙升分析)
《JVM由浅入深学习九】 2024-01-15》JVM由简入深学习提升分(生产项目内存飙升分析)
9 0