其他分享
首页 > 其他分享> > JVM入门请点进来,一起快乐学习JVM吧!

JVM入门请点进来,一起快乐学习JVM吧!

作者:互联网

JVM

前言

以下所有内容,仅针对Hotspot虚拟机而言。

学习一门技术的时候,首当其冲,先百度一下:

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够"一次编译,到处运行"的原因。

OK,百度完了之后就得开始缩句了:

当我们编写完一个程序后,这个程序是如何运行起来的呢,这里简述一下大概的流程:

  1. java程序先被javac编译器编译成.class文件(字节码文件)
  2. JVM运行字节码文件
  3. 经过类加载子系统将字节码文件加载到系统中
  4. 在运行时数据区分配好相应的资源
  5. 执行引擎做相应处理

类加载器子系统

一个字节码文件要被加载到系统中需要三个阶段:

加载阶段

该阶段的加载器分为三种,分别是引导类加载器,扩展类加载器,系统类加载器

三者的底层级别依次递增,即引导类加载器是扩展类加载器的父类加载器,扩展类加载器是系统类加载器的父类加载器。

引导类加载器

扩展类加载器

系统类加载器

双亲委派机制

可能会有小伙伴说这么多加载器,我写一个类都得用到这些加载器去加载吗?
JVM也帮我们想到了这个问题,他提供了双亲委派机制帮我们去解决,双亲委派机制的原理如下:

优点:

沙箱安全机制

因为有了上述的双亲委派机制,所以JVM为我们提供了沙箱安全机制。
举个例子体验下吧!

在javaTest包下自定义一个String类,添加main方法


package javaTest;

public class String {
    public static void main(String[] args) {
        System.out.println("我是自定义的String类");
    }
}

此时我们是运行不了的,因为在加载String类的时候,会因为双亲委派机制一直委派到引导类加载器进行加载,加载的过程中,rt.jar中的String类找不到main方法,所以运行失败。

加载流程

链接阶段

链接阶段又可以细分为3个小阶段

验证

确保在上述加载阶段生成的Class对象中符合当前虚拟机要求,并且不会危害到虚拟机的安全。

准备

解析

初始化阶段

运行时数据区

这个区域是JVM重点关注的区域,可以说是重中之重,说他是核心也不为过。

JVM定义了在程序运行期间会使用到的运行时数据区,大体分为以下5块,这里面有的是线程独立的,随着线程生亡,有些是随着虚拟机生亡;

线程独立的数据区有虚拟机栈,本地方法栈,程序计数器;

虚拟机栈

本地方法栈

程序计数器

这个区域是运行时数据区最小的一个区域,只是用来记录线程的执行地址。

CPU工作的时候需要不停的去切换各个线程,当我们其他线程执行好了后就得回来执行当前的线程,所以就得直到之前执行到哪了,从程序计数器去获取到指定的地址,从那开始执行,避免重复工作。这也是为什么程序计数器是线程私有的,这样才能保证每个线程在进行切换时能够继续上次的工作往下执行,不会线程之间互相干扰。

今天先到这

方法区/元空间

执行引擎

标签:Java,字节,虚拟机,入门,线程,JVM,请点,加载
来源: https://blog.csdn.net/fighting32/article/details/114916774