java面试题jvm字节码的加载与卸载
虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换分析和初始化,最终形成可以被虚拟节直接使用的JAVA类型,这就是虚拟机的类加载机制。
类从被加载到虚拟机内存到卸载出内存的生命周期包括:加载->连接(验证->准备->解析)->初始化->使用->卸载
初始化的5种情况:
1.使用new关键字实例化对象时,读取或设置一个类的静态字段,除被final修饰经编译结果放在常量池的静态字段,调用类的静态方法时。 2.使用java.lang.reflect包方法对类进行反射调用时。(Class.forName())。 3.初始化子类时,如果父类没有初始化。 4.虚拟机启动时main方法所在的类。 5.当使用JDK1.7动态语言支持时,java.lang.invoke.MethodHandle实例解析结果为REF_getStatic,REF_putStatic,REF_invokeStatic的方法句柄,且对应类没有进行初始化。
加载 加载是类加载的第一个阶段,虚拟机要完成以下三个过程:
1.通过类的全限定名获取定义此类的二进制字节流。 2.将字节流的存储结构转化为方法区的运行时结构。 3.在内存中生成一个代表该类的Class对象,作为方法区各种数据的访问入口。
验证 目的是确保class文件字节流信息符合虚拟机的要求。
准备 为static修饰的变量赋初值,例如int型默认为0,boolean默认为false。
解析 虚拟机将常量池内的符号引用替换成直接引用。
初始化 初始化是类加载的最后一个阶段,将执行类构造器< init>()方法,注意这里的方法不是构造方法。该方法将会显式调用父类构造器,接下来按照java语句顺序为类变量和静态语句块赋值。
方法调用
Java是一门面向对象的语言,它具有多态性。那么虚拟机又是如何知道运行时该调用哪一个方法?
静态分派是在编译期就决定了该调用哪一个方法而不是由虚拟机来确定,方法重载就是典型的静态分派。 动态分派是在虚拟机运行阶段才能决定调用哪一个方法,方法重写就是典型的动态分派。
动态分派的实现:当调用一个对象的方法时,会将该对象的引用压栈到操作数栈,然后字节码指令invokevirtual会去寻找该引用实际类型。如果在实际类型中找对应的方法,且访问权限足够,则直接返回该方法引用,否则会依照继承关系对父类进行查找。实际上,如果子类没有重写父类方法,则子类方法的引用会直接指向父类方法。
由Java虚拟机自带的类加载器所加载的类,在虚拟机的生命周期中,始终不会被卸载。
前面介绍过,Java虚拟机自带的类加载器包括根类加载器、扩展类加载器和系统类加载器。
Java虚拟机本身会始终引用这些类加载器,而这些类加载器则会始终引用它们所加载的类的Class对象,因此这些Class对象始终是可触及的。
由用户自定义的类加载器加载的类是可以被卸载的。
具体的例子为:
loader1变量和obj变量间接应用代表Sample类的Class对象,而objClass变量则直接引用它。
如果程序运行过程中,将上图左侧三个引用变量都置为null,此时Sample对象结束生命周期,MyClassLoader对象结束生命周期,代表Sample类的Class对象也结束生命周期,Sample类在方法区内的二进制数据被卸载。
当再次有需要时,会检查Sample类的Class对象是否存在,如果存在会直接使用,不再重新加载;如果不存在Sample类会被重新加载,在Java虚拟机的堆区会生成一个新的代表Sample类的Class实例(可以通过哈希码查看是否是同一个实例)。
java面试题jvm字节码的加载与卸载的更多相关文章
- JVM --字节码的加载
ClassLoader类加载器 常见的类加载器有BootStrapClassLoader<-ExtClassLoader<-AppClassLoader<-用户ClassLoader ...
- Java基础篇(JVM)——字节码详解
这是Java基础篇(JVM)的第一篇文章,本来想先说说Java类加载机制的,后来想想,JVM的作用是加载编译器编译好的字节码,并解释成机器码,那么首先应该了解字节码,然后再谈加载字节码的类加载机制似乎 ...
- Java finally语句到底是在return之前还是之后执行(JVM字节码分析及内部体系结构)?
之前看了一篇关于"Java finally语句到底是在return之前还是之后执行?"这样的博客,看到兴致处,突然博客里的一个测试用例让我产生了疑惑. 测试用例如下: public ...
- JVM 字节码指令手册 - 查看 Java 字节码
JVM 字节码指令手册 - 查看 Java 字节码 jdk 进行的编译生成的 .class 是 16 进制数据文件,不利于学习分析.通过下命令 javap -c Demo.class > Dem ...
- 深入理解JVM—字节码执行引擎
原文地址:http://yhjhappy234.blog.163.com/blog/static/3163283220122204355694/ 前面我们不止一次的提到,Java是一种跨平台的语言,为 ...
- JVM 字节码执行实例分析
前言 最近在看<Java 虚拟机规范>和<深入理解JVM虚拟机>,对于字节码的执行有了进一步的了解.字节码就像是汇编语言,是 JVM 的指令集.下面我们先对 JVM 执行引擎做 ...
- JVM 字节码(四)静态方法、构造代码、this 以及 synchronized 关键字
JVM 字节码(四)静态方法.构造代码.this 以及 synchronized 关键字 一.静态代码 public class ByteCodeStatic { private static fin ...
- JVM 字节码(二)方法表详解
JVM 字节码(二)方法表和属性表 上一节中对 ClassFile 的整体进行了五个详细的说明, 本节围绕 ClassFile 最重要的一个内容 - 方法表的 Code 属性展开 ,更多 JVM Me ...
- JVM总结(五):JVM字节码执行引擎
JVM字节码执行引擎 运行时栈帧结构 局部变量表 操作数栈 动态连接 方法返回地址 附加信息 方法调用 解析 分派 –“重载”和“重写”的实现 静态分派 动态分派 单分派和多分派 JVM动态分派的实现 ...
随机推荐
- 文本溢出后,隐藏显示"..."和margin边距重叠
一.隐藏加省略 单行文本: overflow: hidden; white-space: nowrap; text-overflow: ellipsis; 多行文本: overflow: hidden ...
- laravel查询常用的方式含义.
find($id) 传值并返回一个模型.如果不存在匹配的模型,则返回null.findOrFail($id) 传值并返回一个模型.如果不存在匹配的模型, 它会抛出异常.first() 返回在数据库中找 ...
- npm 更换镜像,解决cnpm仍然太慢的问题
众所周知,npm官方镜像 https://registry.npmjs.org 极为卡顿,所以考虑换国内镜像. 网上很多人都说用淘宝镜像,但是淘宝镜像由于同步过于频繁导致卡顿. 可以使用华为镜像: n ...
- 12.DRF-节流
Django rest framework源码分析(3)----节流 添加节流 自定义节流的方法 限制60s内只能访问3次 (1)API文件夹下面新建throttle.py,代码如下: # utils ...
- C# 9.0 新特性之只读属性和记录
阅读本文大概需要 2 分钟. 大家好,这是 C# 9.0 新特性系列的第 4 篇文章. 熟悉函数式编程的童鞋一定对"只读"这个词不陌生.为了保证代码块自身的"纯洁&quo ...
- Redis安装过程jemalloc/jemalloc.h报错
问题: [root@localhost redis-3.0.0]# make cd src && make all make[1]: Entering directory `/data ...
- unknown directive "" in E:\canteen\nginx-1.16.0/conf/nginx.conf:3-------文本编辑器修改nginx配置文件的坑
nignx小白一个,今天在配置nginx的时候,理所当然的用了文本编辑器编辑并保存了一下nginx的nginx.conf配置文件,一不小心就折腾了几个钟. 保存之后就nginx -s reload一下 ...
- c# 线程的优先级
前言 有时候我们希望某个线程更加重要,希望让其先运行的话.c#为我们提供了线程修改优先级.但是这样的效果有多大呢? 正文 直接放代码: static void Main(string[] args) ...
- 单表数据加载到TreeView(.Node.Level>=2) "蝴蝶效应" SelectedNode注意事项 效能优化 综合问题
using System; using System.Collections.Generic; using System.ComponentModel; using System.Configurat ...
- 常用的rac搭建相关
平时自己测试环境搭建用,部分参数是不规范的. 生产请按照官方文档或者公司标准化文档来做. 共享硬盘: disk.locking = "FALSE" diskLib.dataCach ...