java虚拟机基础知识

1.java虚拟机与程序的生命周期
在如下几种情况下,java虚拟机将结束生命周期
a.执行了System.exit()方法
b.程序正常执行结束
c.程序在执行过程中遇到了错误或异常而异常终止
d.由于操作系统错误而导致java虚拟机进程终止

2.java虚拟机工作过程为加载,连接与初始化
加载:查找并加载类的二进制数据到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个Class对象,用来封装类在方法区类的数据结构

连接:将读入带内存的二进制数据合并到虚拟机的运行时环境中
a.验证:确保被加载类的正确性
1>类文件的结构检查
2>语义检查
3>字节码验证
4>二进制兼容性的验证
b.准备:为类的静态变量分配内存,并将其初始化为默认值
c.解析:把类中的符号引用转换为直接引用

初始化:把类中的静态变量赋予正确的初始值
a.假如这个类还没有被加载和连接,那么先加载和连接
b.假如这个类存在直接的父类,并且这个父类没有被初始化,先初始化直接的父类
c.假如类中存在初始化语句,依次执行这些初始化语句
d.当虚拟机初始化一个类时候要求所有父类已经被初始化,但这条规则不使用于接口,在初始化一个类时,并不会先初始化它所实现的接口
e.在初始化一个接口时,并不会先初始化它的父接口,只有当程序首次使用指定接口的静态变量时,才会导致该接口的初始化

3.java程序对类的使用方式可以分为主动使用和被动使用,所有的java虚拟机实现必须在每个类或者接口被java程序首席主动使用时才初始化他们,主动使用有以下几种情况,其它情况均为被动使用
a.创建类的实例
b.访问某个类或者接口的静态变量,或者对静态变量赋值
c.调用类的静态方法
d.反射
e.初始化一个类的子类
f.java虚拟机启动时被标明为启动类的类

4.java提供了两种类型的类加载器
a.java虚拟机自带的加载器
根类加载器(Bootstrap)
扩展类加载器(Extension)
系统类加载器(System)
b.用户自定义的类加载器
java.lang.ClassLoader的子类,用户可以自定义类的加载形式
java虚拟机规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的
过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误,如果这个类一直没有被程序主动使用,那么类加载器不会报告错误

5.类加载器
类加载器用来把类加载到java虚拟机中,从JDK1.2版本开始,类的加载器过程采用父亲委托机制,这种机制能更好保证java平台的安全,在此委托机制中,除了虚拟机自带的根类加载器以外,其余的类加载器都有且只有一个父类加载器

根类加载器:负责加载虚拟机的核心类库,如java.lang.*等,根类加载器的实现依赖于底层操作系统,它并没有继承java.lang.ClassLoader,因为它是用C++所写

扩展类加载器:它的父加载器为根类加载器,他从java.ext.dirs系统属性所指定的目录中加载类库,或者从JDK的安装目录的jre\lib\ext子目录下加载类库,如果用户把自己创建的jar放在该目录下也会由扩展加载器自动加载,它是纯java类,属于java.lang.ClassLoader的子类

系统类加载器:也成为应用加载器,它的父类加载器为扩展加载器,它从环境变量classpath或者系统属性path所指定的目录中加载类,他是用户自定义的类加载器的默认父加载器,它是纯java类,也是java.lang.ClassLoader的子类

每个类加载器都有自己的命名空间,命名空间由该加载器和其所有父类加载器所加载的类组成,在同一个命名空间中不会出现类的完整名字相同的两个类,在不同的命名空间中可以出现,同一个命名空间内的类是相互可见的,子加载器的命名空间包含所有父加载器的命名空间,所有子加载器加载的类能看见父加载器加载的类,但是父加载器不能看见子加载器加载的类

由同一类加载器加载的属于相同包的类组成了运行时包,决定两个类是不是属于同一个运行时包,不仅要看它们的包名是否相同,还要看定义类加载器是否相同,只有属于同一运行时包的类才能互相访问包可见的类和类成员,这样的限制能避免用户自定义的类冒充核心类库去访问核心类库的类和成员

下面是一个自定义加载器的小例子
首先是要被加载的两个类

public class Sample {
public Sample() {
System.out.println("Sample is loaded by:"
+ this.getClass().getClassLoader());
new Dog();
}
}




public class Dog {
public Dog(){
System.out.println("Dog is loaded by:" + this.getClass

().getClassLoader());
}
}


然后是自定义加载器

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader {
private String path = null;
private String name = null;
private String classType = ".class";

public MyClassLoader(String name) {
this.name = name;
}

public MyClassLoader(ClassLoader classLoader, String name) {
super(classLoader);
this.name = name;
}

@Override
public String toString() {
return this.name;
}

public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path;
}

public Class<?> findClass(String name) throws ClassNotFoundException {
byte[] b = loadClassData(name);
return defineClass(name,b,0,b.length);
}

public byte[] loadClassData(String name) {
InputStream is = null;
ByteArrayOutputStream baos = null;
int ch = 0;
byte[] data = null;
try {
is = new FileInputStream(new File(path+name+classType));
baos = new ByteArrayOutputStream();
while(-1 != (ch=is.read())){
baos.write(ch);
}
data = baos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
is.close();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return data;
}
public static void main(String[] args) throws Exception {
//定义loader1加载器,默认父加载器为系统加载器,并设置其加载目录
MyClassLoader loader1 = new MyClassLoader("loader1");
loader1.setPath("d:\\test\\serverlib\\");

//定义loader2加载器,指定其父加载器为loader1,并设置其加载目录
MyClassLoader loader2 = new MyClassLoader(loader1,"loader2");
loader2.setPath("d:\\test\\clientlib\\");

//定义loader3加载器,指定其父加载器为根类加载器,并设置其加载目

录
MyClassLoader loader3 = new MyClassLoader(null,"loader3");
loader3.setPath("d:\\test\\otherlib\\");

testLoader(loader2);
testLoader(loader3);
}

public static void testLoader(MyClassLoader loader) throws Exception {
//将sample类加载进来,底层会调用findClass
Class clazz = loader.loadClass("Sample");
//对类的主动使用
Object object = clazz.newInstance();
}

}


在D盘新建对应的目录,当调用testLoader(loader2);时,由于父托管机制,它会先让loader1加载器去加载,而loader1的加载目录在d:\\test\\serverlib\\目录下,将Sample类和Dog类的.class文件放置该目录下,当调用testLoader(loader3);时,由于loader3的父类加载器为根类加载器,它不会对Sample和Dog进行加载,这时候只能由loader3加载器进行加载,而它加载的目录为d:\\test\\otherlib\\,将Sample类和Dog类的.class文件放置该目录下,最后将MyClassLoader.class文件放置在D盘根目录下,通过DOS窗口运行将会看到以下结果
Sample is loaded by:loader1
Dog is loaded by:loader1
Sample is loaded by:loader3
Dog is loaded by:loader3
uniapp - 详细实现移动端公众号 H5 网页授权登录流程及示例代码,申请测试公众号全流程及本地调试无需部署上线服务器就能直接调起微信登陆授权页面,手机移动端h5公众号页面利用微登录拿到用户数据! uni-app,微信公众号,h5网页,uniapp网页端,手机端H5公众号页面,微信网页登陆,uniApp详细实现公众号的登录,微信授权第三方网站登录,流程及逻辑详细教程,OAuth2.0,公众号网页授权,微信网页授权通过code换取网页授权,redirect_url,参数错误,解决,报错,无法调起,如何申请测试公众号,微信公众平台测试号的申请与使用,获取用户openid手机号昵称头像,利用测试号实现本地调试微信登录授权,本地无法调试怎么办,测试公众号,在开发环境下怎么测试,用项目本地ip地址,微信公众号平 阅读详情

相关推荐

5分钟搞定阿里云千问大模型API申请:手把手教你获取API Key

本文提供了一份高效的阿里云通义千问大模型API Key获取实战指南。通过清晰的步骤,帮助开发者在五分钟内完成从账号准备、精准导航控制台到创建并验证API Key的全过程,并强调了密钥安全管理和基础调用测试的重要性,助力快速集成AI能力。

ol789012345的博客 1344

类初始化的时机-接口

当Java虚拟机初始化一个类时,要求它的所有父类都已经被初始化,但是这条规则并不适用于接口。 在初始化一个类时,并不会先初始化它所实现的接口 在初始化一个接口时,并不会先初始化他的父接口 因此,一个父接口并不会因为他的子接口或者实现类的初始化而初始化。只有当程序首次使用特定接口的静态变量时,才会导致该接口的初始化。 ...

qq_40807366的博客 232

利用VBA宏实现LightTools仿真数据自动化导出至Excel

本文详细介绍了如何利用VBA宏实现LightTools仿真数据自动化导出至Excel的完整流程。通过调用LTAPI接口,工程师可以自动执行仿真、抓取照度与光强等数值数据、捕获并粘贴仿真图像,从而将重复性工作自动化,显著提升光学设计工作的效率和准确性。

weixin_28314575的博客 499

初始化对于类与接口的异同点深入解析

在上一次【http://www.cnblogs.com/webor2006/p/8905978.html】中学习了类加载器理论的一些内容,其中回顾一下关于类的初始化时机的这段文字: 而截图中也说明了这个结论在之前篇幅中也已经详细说明过了,那再拧出来有何意义呢?因为以前举的例子并不能很好的说明上面的结论,为什么,先来回顾一下当时的代码: 其中当时是这么论证“当一个接口在初始化时,并不要求...

weixin_30415801的博客 187

【AI知识点】启发式算法(Heuristic Algorithms)

启发式算法(Heuristic Algorithms) 是一种基于经验、直觉和局部优化的求解问题的算法,尤其适用于解决计算复杂度高、规模庞大的问题。它们通过简化问题、局部搜索和快速近似,提供了一种在短时间内获得“足够好”解的途径。虽然启发式算法无法保证全局最优解,但它们在实际应用中广泛使用,特别是在优化问题、任务调度和机器学习等领域。

AI完全体 3031

Conda环境创建报错?教你快速解决Solving environment: failed和ResolvePackageNotFound问题

本文深入解析Conda环境创建中常见的'Solving environment: failed'和'ResolvePackageNotFound'报错原因,并提供从基础到高级的系统化解决方案。涵盖渠道配置、版本通配、环境文件编辑等实用技巧,帮助开发者快速解决conda环境创建问题,提升工作效率。

weixin_28677451的博客 258

java类的生命周期

关键字: class 类加载 1 类的加载 1 概念:类的加载就是把类的.class文件中的二进制数据读入到内存中。把它存放在java运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。 2 来源: JVM可以从多种来源加载类的class德二进制数据 1从本地文件系统加载类的cla...

weixin_30646505的博客 117

uCOS中的消息邮箱(:task与task之间传递一个数据(数据缓冲区))

程序需求,需要完成task与task之间  字符数组的数据传输 比如:在ucos中,串口2接收的字符数组是不定时的&不定长的;只有当接收到数据的时候_才将数据赋值给新数组 具体的程序示意如下: 图1:消息邮箱测试中的     向消息邮箱发送消息(OSMboxPost(Str_Box,(void*)rec);//发送消息--(向 消息邮箱_msg_key发送消息) ),实际项目需求的

faguoduifangui的博客 4540

深入java虚拟机(一)

一:类加载器深入剖析1.java虚拟机与程序的生命周期2.在如下几种情况下,java虚拟机将结束生命周期   -- 执行了System,exit()方法   --程序正常执行结束   --程序在执行过程中遇到了异常或者错误而异常终止   --由于操作系统出现错误而导致java虚拟机进程终止二:类的加载,连接与初始化   --加载:查找并加载类的二进制数据   --连接:             -...

窃格瓦拉-梦 622

2021秋招IC验证面经-ARM中国/中科芯/飞腾/地平线/中兴

中科芯 (央企福利待遇好,但是百分百不解决户口,适合当地人进去躺平。) 现场面试,三个面试官,时间大约40min 首先介绍一下自己,介绍一下项目。所做项目用到了FIFO吗,深度是多少,位宽是多少,仲裁算法是什么? 验证环境中的reference model是自己写的还是本身就有的,仲裁怎么在参考模型中实现,参考模型怎么获取寄存器的值? 怎么配置RTL寄存器,通过平台的寄存器模型进行寄存器配置,寄存器模型里边的方法,写一个寄存器或读一个寄存器怎么实现? 寄存器如何实现前门访问和后门访问,后门访问时

weixin_48014653的博客 6319

uniapp - [微信小程序 | 安卓苹果app] 详细实现接入天地图完整流程,提供显示地图、IP 属地定位 / 用户定位的城市名称、用户定位的经纬度超多功能(复制运行示例代码,详细注释及常见问题)

uni-app,微信小程序,安卓app,苹果app,App端,支付宝小程序,nvue,天地图,国家天地图api,接入使用天地图,uniApp小程序端接入天地图,uniapp安卓苹果app端接入天地图,微信小程序平台如何引入天地图,天地图Api使用教程,如何在uniapp里集成天地图,使用天地图获取当前定位,天地图api教程,天地图官方文档,天地图详细使用教程,Uniapp项目如何使用天地图,项目引入天地图配置及使用教程,使用天地图获取用户定位,天地图获取用户当前位置信息(经纬度),如何通过天地图拿到用户定位

🏆 前端领域优质创作者 1万+

JVM对类的处理

1.类的加载 加载:查找并加载类的二进制数据。把.class文件的二进制数据读入到内存中,把它存放在运行时数据区的方法区内,然后在堆区中创建一个java.lang.Class对象(这就是类加载的最终产品),用来封装类在方法区内的数据结构,并且向JAVA程序提供了访问类在方法区内的数据结构的接口。 2.类的验证: 验证:确保加载类的正确性,检查的内容包括,类文件的结构检查,语义检查,...

xiaoer 152

LIN协议V2.2A版介绍

IN 协议规范2.2A 版(2010 年 12 月发布)是面向低成本汽车网络的标准,核心采用单主多从架构,支持最高20kbit/s速率,通过单总线实现通信;定义了完整的协议栈(含协议层、传输层、物理层等),规定了帧结构(含 Break 字段、Sync 字节、保护标识符 PID、数据字段、校验和)、5 类帧类型(无条件帧、事件触发帧等)及调度表机制以保障确定性传输;

qflook的博客 319

Java虚拟机基础知识整理

JVM基础知识

努力学习Java的彬彬的博客 841

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java虚拟机基础知识

Java虚拟机基础知识 写在前面 之前老大让做一些外包面试,我的问题很简单: 介绍一下工作中解决过比较有意思的问题。HashMap使用中需要注意的点。 第一个问题主要是想了解一下对方项目经验的含金量,第二个问题则是测试下是否知道一些细节,比如HashMap是线程不安全的、用HashMap来做缓存的话可能导致内存泄露等,自我感觉问题设计的还可以:D~ 但是看了其他同事

AlbenXie的博客 574

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

java基础知识总结二java虚拟机以及虚拟机调优

我们在学习java的时候,离不开java虚拟机,所以了解Java虚拟机在后来的开发,寻找BUG的时候非常有用。并且对于代码调优也非常实用。 一:Java虚拟机结构 1:结构。 线程私有的: 程序计数器 虚拟机栈 本地方法栈 线程共享的: 堆 方法区 直接内存 (非运行时数据区的一部分) 2:介绍 (1):程序计数器 序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节...

wszhm123的博客 248

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Java 虚拟机基础知识

类加载机制 类加载阶段 加载:查找字节流,创建类。 双亲委派模型:boot class loader,extension class loader,application class loader 链接: 验证: 准备:静态字段分配内存 解析 :符号引用解析 初始化:静态字段初始化 内存布局 堆 方法区 Java虚拟机栈 本地方法栈 PC 寄存器 垃圾回收 确定垃圾 回收 工具 ...

菜鸟日常 292

java虚拟机需要学多久_java虚拟机学习需要掌握哪些基础知识

随着互联网的不断发展,越来越多的人都在学习java编程开发语言,而今天我们就通过案例分析来了解一下,java虚拟机学习需要掌握哪些基础知识。一、面向对象编程的概念这是一个本身,也更需要知道这些对象在java的面向对象编程概念中是如何体现出来的,这样更有利于开发者掌握java这门开发语言,以及其他面向对象编程的语言。在这里只是简单罗列了一下,主要的知识点包括有:面向对象三大特性:封装,继承,多态;各...

weixin_29337315的博客 342

Java虚拟机(jdk1.8) 学习笔记 (虚拟机基础知识介绍)

Java虚拟机学习笔记

此物最相思 599

Java虚拟机基础知识总结

jvm

weixin_46134317的博客 568

JVM虚拟机系列 - 基础知识之Java运行时区域&&HotSpot内部对象解密

背景 要想学懂JVM,必须先搞清楚JVM的基础知识,基础知识从《深入理解Java虚拟机,第三版》整理而来,通过思维导图的方式更加清晰。 思维导图

阿健小站 205

Java虚拟机基础知识汇总 (一)

本文总结了我在学习过程中遇到的JVM相关知识,都是最基本的介绍,作为自我总结,也希望能对看到本博客的你带来帮助~1. Java虚拟机Java虚拟机(Java Virtual Machine,JVM)是一种能够运行Java字节码的虚拟机,它有完善的硬件架构和相应的指令系统。 Java字节码是Java虚拟机执行的一种指令格式,Java源文件经过编译器,能够被编译成被Java虚拟机执行的字节码文件。下图

gxx_csdn的博客 639
上一篇: HashMap底层的实现
下一篇: java之网络编程
lk231_java
博客等级 码龄15年 0粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值