JVM(一) 类加载器、类加载过程、JVM参数设置

news2024/11/26 14:24:50

JVM

Java编译器

Java源文件在通过编译器之后被编译成相应的.Class文件(字节码文件)

JVM解释器

.Class文件又被JVM中的解释器编译成机器码在不同的操作 系统(Windows、Linux、Mac)上运行。每种操作系统的解释器都是不同的,但基于解释器实现的虚拟机是相同的,这也是Java能够跨平台的原因。

JVM结构

Java程序的具体运行过程如下。
(1)Java源文件被编译器编译成字节码文件。
(2)JVM将字节码文件编译成相应操作系统的机器码。
(3)机器码调用相应操作系统的本地方法库执行相应的方法。
Java 虚 拟 机 包 括 一 个 类 加 载 器 子 系 统 ( Class Loader SubSystem)、运行时数据区(Runtime Data Area)、执行引擎和本地接口库(Native Interface Library)。

类加载器子系统:
类加载器子系统用于将编译好的.Class文件加载到JVM中(后面有详细介绍)

执行引擎和本地方法接口:

执行引擎包括即时编译器和垃圾回收器,即时编译器用于将Java字节码编译成具体的机器码,垃圾回收器用于回收在运行过程中不再使用的对象;
本地接口库用于调用操作系统的本地方法库完成具体的指令操作

运行时数据区:

运行时数据区用于存储在JVM运行过程中产生的数据,包括程序计数器、方法区、本地方法区、虚拟机栈和虚拟机堆;
  • 方法区:存储已被虚拟机加载的类元数据信息(元空间)
  • 堆:存放对象实例,几乎所有的对象实例都在这里分配内存
  • 虚拟机栈:虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息
  • 程序计数器:当前线程所执行的字节码的行号指示器
  • 本地方法栈:本地方法栈则是为虚拟机使用到的Native方法服务

JVM的生命周期

虚拟机的启动

java虚拟机通过引导类加载器(bootstrap ClassLoader)创建一个初始类(initial class)来完成,这个类是由虚拟机的具体实现指定的

虚拟机的执行

一个运行中的java虚拟机有着一个清晰的任务:执行java程序

执行一个java程序的时候,真真正正在执行的是一个叫做java虚拟机进程

虚拟机的退出

有如下几种退出的情况

1.程序正常执行结束

2.程序在运行的过程中遇到了异常或错误而异常终止

3.由于操作系统出现错误而导致java虚拟机进程终止

4.某线程调用Runtime类或System类的exit方法或Runtime类的halt方法


类加载

ClassLoader

类加载器子系统ClassLoader负责加载class文件,class文件在文件开头有特定的文件标示,并且ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。

类加载器分为四种:前三种为虚拟机自带的加载器。

  • 启动类加载器(Bootstrap)C++

    负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类

  • 扩展类加载器(Extension)Java

    负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包

  • 应用程序类加载器(AppClassLoader)Java

    也叫系统类加载器,负责加载classpath(java.class.path)中指定的jar包及目录中class

  • 用户自定义加载器 Java.lang.ClassLoader的子类,用户可以定制类的加载方式

public class LockDemo {
    public static void main(String[] args) {
        //LockDemo 是用户的自定义类 由应用类加载器加载 它的父类加载器是扩展类加载  扩展类的父类加载器是启动类加载器
        //AppClassLoader
        System.out.println(LockDemo.class.getClassLoader());
        //ExtClassLoader
        System.out.println(LockDemo.class.getClassLoader().getParent());
        //启动类加载器是C++实现的  java中无法获取
        System.out.println(LockDemo.class.getClassLoader().getParent().getParent());

        //String是rt包中的类
        System.out.println("===========================");

        System.out.println(String.class.getClassLoader());
        System.out.println(String.class.getClassLoader().getParent());
        System.out.println(String.class.getClassLoader().getParent().getParent());
    }
}

控制台运行效果:符合预期

打印控制台中的sun.misc.Launcher,是一个java虚拟机的入口应用

各种类加载器所加载的文件

public static void main(String[] args) {
    //应用类加载器会加载 当前项目编译后的classess目录下的所有的文件
    System.out.println("AppClassLoader加载的文件: ");
    System.out.println(System.getProperty("java.class.path"));
    System.out.println("ExtClassLoader加载的文件: ");
    System.out.println(System.getProperty("java.ext.dirs"));
    //启动类加载器加载路径
    System.out.println("BootstrapClassLoader加载的文件: ");
    for (URL url : Launcher.getBootstrapClassPath().getURLs()) {
        System.out.println(url);
    }
}

双亲委派模型

classloader的双亲委托机制是指多个类加载器之间存在父子关系的时候,某个class类具体由哪个加载器进行加载的问题。

如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上

工作过程:

  • 1、当AppClassLoader加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器ExtClassLoader去完成。

  • 2、当ExtClassLoader加载一个class时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给BootStrapClassLoader去完成。

  • 3、如果BootStrapClassLoader加载失败(例如在$JAVA_HOME/jre/lib里未查找到该class),会使用ExtClassLoader来尝试加载;

  • 4、若ExtClassLoader也加载失败,则会使用AppClassLoader来加载

  • 5、如果AppClassLoader也加载失败,则会报出异常ClassNotFoundException

捕获式加载

双亲委派模型好处

安全,可避免用户自己编写的类动态替换Java的核心类,如java.lang.String ,防止内存中出现多份同样的字节码(安全性角度)

通过这种层次模型,可以避免类的重复加载,也可以避免核心类被不同的类加载器加载到内存中造成冲突和混乱,从而保证了Java核心库的安全。


类加载过程

ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。

阶段一:加载阶段

阶段一主要就是生成了Class对象

那么加载的字节码文件来源于哪里?

阶段二:链接

验证

字节码文件在文件开头有特定的文件标识,CA FE BA BE

===================

准备

====================

解析

阶段三:初始化

clinit方法,有类变量的赋值会自动帮我们生成该方法

clinit方法注意点

也就是说:多线程并发情况下一个类只会被加载一次 

===============

一个小测试,非法的前向引用

================ 

init方法

构造器对应字节码文件中 init方法。

任何一个类声明以后,内部至少存在一个类的构造器


PC寄存器

每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向下一条指令的地址,即 将要执行的指令代码),由执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不记。

JVM参数设置

堆空间的常用参数设置

Java堆区在JVM启动的时候即被创建,其空间大小也就确定。是JVM管理的最大一块内存空间。堆内存的大小是可以调节的。

怎么对jvm进行调优?通过参数配

官网: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

java代码查看jvm堆的默认值大小:

//堆的最大值,默认是内存的1/4
System.out.println("max : "+Runtime.getRuntime().maxMemory()*1.0/1024/1024+" MB ");
//堆的当前总大小,默认是内存的1/64
System.out.println("init : "+Runtime.getRuntime().totalMemory()*1.0/1024/1024+" MB ");


在哪里设置JVM参数

idea运行时设置方式如下:

不加分号,中间有空格。

-Xms10m  -Xmx30m

重新测试这段代码:

System.out.println("max : " + Runtime.getRuntime().maxMemory() * 1.0 / 1024 / 1024 + " MB ");
System.out.println("init : " + Runtime.getRuntime().totalMemory() * 1.0 / 1024 / 1024 + " MB ");

控制台打印如下:

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

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

相关文章

SpringBoot起步依赖和配置

目录 起步依赖 目的 1 继承父工程,确定版本信息 2 添加 starter-web 坐标信息 配置 配置文件的分类 ​编辑实操 1 后缀名是.properties文件修改端口号,把原本的默认端口号8080改为8082 2 创建后缀名是.yaml文件,尝试修改端口号&…

ARM——体系结构

计算机体系结构:冯诺伊曼 哈佛 冯诺依曼结构 冯诺依曼结构,也称冯诺依曼模型或普林斯顿结构,是根据冯诺依曼提出的存储程序概念设计的计算机体系结构。其主要特点包括: 存储程序:指令与数据都…

【Qt】信号与槽(下)

目录 自定义信号 带参数的信号和槽 信号和槽存在的意义 信号与槽的连接方式 一对一 一对多 多对一 意义 信号和槽的其他说明 信号和槽的断开 使用Lambda表达式定义槽函数 信号与槽的优缺点 优点: 松散耦合 缺点: 效率较低 自定义信号 自定义槽函数是非常关键的&a…

VMware 安装 centos7.9教程

目录 VMware17安包装 1.创建新的虚拟机 2.稍后安装一个系统 3.选择Centos7 4.选择安装位置 5.指定磁盘内存大小 6.自定义硬件 7.编辑内存 8.编辑处理器 9.选择安装镜像位置 10.选择网络适配器 11.播放虚拟机 12.选择语言简体中文 13.选择时区时间 14.最小化安装 …

电机学习-基础知识

文章目录 1 基本物理概念1.1 左手定则1.2 安培定则1.3 感应电动势 2 电机简单分类2.1 直流有刷电机2.2 步进电机2.2.1 步进电机的驱动原理1.相与线2.极性3.步进电机的驱动 2.3 无刷电机2.3.1 充磁方式2.3.2正弦波电动势与梯型电动势 3 编码器3.1 霍尔编码器3.2 光电编码器3.3 增…

TexWorks配置使用latexmk实现增量编译

TexWorks配置使用latexmk实现增量编译 TexWorks默认使用pdfLaTeXMakeIndexBibTeX,修改后,重新编译等待时间较长。本文旨在说明配置TexWorks使用latexmk实现增量式编译,加速编译。 前置条件说明 (1) 通过miktex自动安装了TexWorks及自带pdf…

Docker相关配置记录

Docker相关配置记录 换源 {"registry-mirrors": ["https://dockerhub.icu","https://docker.chenby.cn","https://docker.1panel.live","https://docker.awsl9527.cn","https://docker.anyhub.us.kg","htt…

VisionPro二次开发学习笔记12-使用CogToolGroup控件进行图像检测

本示例演示了如何通过图像数据库使用 CogImageFileTool,并将其放入 CogToolGroup 中,对于数据库中的每个图像运行一次检测. 当用户按下 运行 按钮时,程序执行以下操作: 如果工具组中没有 CogImageFileTools,它将显示一…

Codeforces Pinely Round 4 (Div. 1 + Div. 2) A~G

A.Maximize the Last Element(枚举) 题意: 给你一个由 n n n个整数组成的数组 a a a,其中 n n n是奇数。 在一次操作中,你将从数组 a a a中删除两个相邻的元素,然后将数组的剩余部分连接起来。例如&…

轻松构建Electron应用:TypeScript与esbuild的完美搭档

简介 使用 TypeScript (TS) 编写 Electron 应用程序带来了许多好处,以下是一些主要优势: 类型安全:TypeScript 是一种静态类型语言,它在编译时检查类型错误,这有助于在开发过程中及早发现潜在的错误。更好的工具支持…

RK3568平台(背光篇)背光调试常见问题

一.屏幕背光概述 背光就是屏幕的从里往照射的光。 LCD 主要由液晶面板、背光、驱动电路等组成,液晶面板不会主动发光,需要背光源才能显示,液晶面板的作用就是通过电压改变某像素光的透过率来显示的,当然此光要求是偏振光&#x…

数据结构(5.5_3)——并查集的进一步优化

Find操作的优化(压缩路径) 压缩路径——Find操作,先找到根节点,再将查找路径上所有结点都挂到根结点下 代码: //Find "查"操作优化,先找到根节点,再进行"路径压缩" int Find(int S[], int x) {…

Shell、C/C++、Python操作环境变量

环境变量 环境变量是一种在操作系统中用于存储信息的机制,这些信息可以被系统进程、应用程序和脚本访问和使用。环境变量在操作系统中的作用类似于一个全局配置参数,它们定义了操作系统的运行环境,包括系统行为、应用程序路径、用户信息等。…

uniapp自定义浮动图标、列表布局

uniapp自定义浮动图标 <button class="fab" @click="goPage"><image src="../../../static/yiyuan.png" mode="" style="width: 60rpx;height:60rpx;"></image></button>.fab {z-index: 100;positi…

TLE4966-3G带方向检测功能的高灵敏度汽车霍尔开关

TLE4966-3G是一款集成电路双霍尔效应传感器&#xff0c;专为使用旋转极轮的高精度应用而设计。通过片上有源补偿电路和斩波器技术实现精确的磁切换点和高温稳定性。 该传感器在Q2提供速度输出&#xff0c;其状态&#xff08;高或低&#xff09;与磁场值相对应。对于超过阈值BO…

小白零基础学数学建模系列-Day3-线性回归模型的构建与评估

文章目录 1 线性回归基础1.1 线性回归概念与应用1.2 数学原理与推导1.3 线性回归的实现 2 案例分析&#xff1a;房价预测2.1 加载数据2.2 数据预处理2.3 探索性数据分析2.4 观察选择特征2.5 准备训练模型的数据2.6 将数据拆分为训练集和测试集2.7 训练和测试模型2.8 模型评估 3…

Ubuntu每次登录都提示有新的更新,apt更新却0个软件需要升级:清空MOTD消息 安装update-notifier-common组件 运行强制更新脚本

问题 每登录ubuntu&#xff0c;都会显示有更新需要注意。 80更新可以立即应用。 这些更新中有 1 个是标准安全更新。 要查看这些附加更新&#xff0c;请运行&#xff1a;apt list --upgradable 然而使用更新命令却提示0可更新 查询了一下&#xff0c;这似乎是MOTD的错误&#x…

Gartner发布2024年网络风险管理成熟度曲线:使网络安全战略与业务目标保持一致的概念、方法、流程和技术

网络风险管理现在是高管和监管机构最关注的问题&#xff0c;它采用多种方法和技术来支持治理、风险管理和合规性。安全和风险管理领导者可以使用此技术成熟度曲线来评估解决方案并做出适当的采用决策。 战略规划假设 到 2026 年&#xff0c;60% 的网络安全职能将实施以业务影响…

【Qt】Qt编程注意事项

目录 Qr中的命名规范 Qt Creator中的快捷键 查询文档的方式 Qt窗口坐标体系 Qr中的命名规范 在学习编程语言阶段&#xff0c;给变量、函数、文件、类命名是非常有讲究的。 命名要有描述性&#xff0c;不要使用abc&#xff0c;xyz这种比较无规律的名字类描述。如果名字比较…

什么是前端微服务,有何优势

随着互联网技术的发展&#xff0c;传统的单体应用架构已经无法满足复杂业务场景的需求。微服务架构的兴起为后端应用的开发和部署提供了灵活性和可扩展性。与此同时&#xff0c;前端开发也经历了类似的演变&#xff0c;前端微服务作为一种新兴的架构模式应运而生。 一、前端微服…