JVM简介及类加载机制(一)
JVM介绍:
目标:JVM运行字节码文件,根据JVM的日志调节程序,对于底层原理有一定的了解
1. 类加载
在JAVA代码中,类型的加载,连接与初始化都是在程序运行期间完成的,提供了灵活性增加了更多的可能性
2. 类加载器(加载类的工具)
虚拟机结束生命周期的情况
A) 执行System.exit(),finally中的代码都不能执行
B) 程序正常结束
C) 程序在执行过程当中碰到异常或异常终止
D) 操作系统出现错误
3.类的加载,连接,初始化
加载:查找并加载类的二进制(把类的二进制文件加载到内存里面)
连接:
A) 验证:确保加载类的正确性
B) 准备:为类的静态变量分配内存,并将其初始化为默认值
例子:
Class Test{
public static int a=1;
}
这个阶段将赋予a默认值0,赋值阶段在后面完成
C) 解析:把类中的符号引用转换为直接引用
符号引用:一个方法里面引用令一个方法
直接引用:指针直接指向方法的内存中的地址
初始化阶段:为类的静态变量分配正确的值,如上例中将1赋值给a
4.类的使用和卸载
类的使用分为主动使用和被动使用
所有的java虚拟机实现必须在每个类或接口被java”首次主动使用”(静态代码块只执行 一次)时才初始化他们
主动使用:
A) 创建类的实例(new 一个对象)
B) 访问某个类或接口的静态变量,或对该静态变量赋值
C) 调用类的静态方法
D) 反射(Class.forName(Class clazz))
E) 初始化一个类的子类(初始化子类时会先初始化父类)
F) Java虚拟机启动时被标明为启动类的类
G) 1.7以后提供了动态语言的支持
被动使用:
除了以上7种都是被动使用,不会导致类的初始化
5.类的加载
将.class的二进制数据读入内存当中,并将其放在运行时数据区的方法区内,然后在内存中创建java.lang.Class对象,用来封装类在方法区的数据结构
6.加载.class的方式
A)从本地系统直接加载
B)网络下载.class文件
C)压缩包里面下载
D)将java源文件动态编译成.class文件(动态代理)
下面来看个例子1:
public class Test1 {
public static void main(String[] args) {
System.out.println(MyChild.str);
}
}
class MyParent{
public static String str="hello world"; static{
System.out.println("myparent block");
}
}
class MyChild extends MyParent{
static{
System.out.println("mychild block");
}
}
console
myparent block
hello world
再看看下面这个
public class Test1 {
public static void main(String[] args) {
System.out.println(MyChild.str2);
}
}
class MyParent{
public static String str="hello world"; static{
System.out.println("myparent block");
}
}
class MyChild extends MyParent{
public static String str2="hello world11";
static{
System.out.println("mychild block");
}
}
console
myparent block
mychild block
hello world11
注:在子类在初始化是要先初始化父类
-XX:+TraceClassLoading 打印加载类的信息
+表示开关
例子2:
public class Test2 {
public static void main(String[] args) {
System.out.println(MyParent1.str);
}
}
class MyParent1{
public static String str="hello";
static{
System.out.println("parent block");
}
}
这个结果不必多说
parent block
hello
如果静态变量加了final呢?
public class Test2 {
public static void main(String[] args) {
System.out.println(MyParent1.str);
}
}
class MyParent1{
public static final String str="hello";
static{
System.out.println("parent block");
}
}
console
hello
那是因为什么呢?原因很简单
那就是常量在编译阶段就会存入到调用该常量的方法的类的常量池当中
下面说一些助记符的意义
ldc表示将int,float或是string类型的常量值从常量池中推送至栈顶(马上就要使用)
Blpush:表示字节(-128-127)的常量推送至栈顶
Sipush:将短整形常量值推送至栈顶
Iconst_1表示将int型的数字1推送至栈顶(Iconst_1-Iconst_5)
那再来看看下面这个例子3
public class Test3 {
public static void main(String[] args) {
System.out.println(MyParent2.str);
}
}
class MyParent2{
public static String str=UUID.randomUUID().toString();
static{
System.out.println("parent block");
}
}
console
parent block
6eb597fb-e999-40f8-8dc9-bf57c9124914
不知道结果与你的预期是否相同?
原因:当一个常量的值在编译期间不能确定,那么七值就不会放到调用类的常量池当中。这时当程序在运行时,会导致主动使用这个常量所在的类,就会导致该类初始化
下面再来看一个例子
public class Test4 {
public static void main(String[] args) {
//MyParent4 m4=new MyParent4();
MyParent4[] m4=new MyParent4[1];
}
}
class MyParent4{
static{
System.out.println("parent block");
}
}
这代表了什么?
MyParent4[] m4=new MyParent4[1];这个并不会主动使用
对于数组来说,其类型时JVM再运行期间动态生成的
JVM简介及类加载机制(一)的更多相关文章
- 【JVM】JVM系列之类加载机制(四)
一.前言 前面分析了class文件具体含义,接着需要将class文件加载到虚拟机中,这个过程是怎样的呢,下面,我们来仔细分析. 二.什么是类加载机制 把class文件加载到内存,并对数据进行校验.转换 ...
- JVM之虚拟机类加载机制
有兴趣可以先参考前面的几篇JVM总结: JVM自动内存管理机制-Java内存区域(上) JVM自动内存管理机制-Java内存区域(下) JVM垃圾收集器与内存分配策略(一) 我们知道,在编写一 ...
- 图解JVM和Tomcat类加载机制
说到本篇的tomcat类加载机制,不得不说翻译学习tomcat的初衷. 之前实习的时候学习javaMelody的源码,但是它是一个Maven的项目,与我们自己的web项目整合后无法直接断点调试.后来同 ...
- 深入理解JVM,虚拟机类加载机制
类加载过程概览 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括以下7个阶段: 加载(Loading) 验证(Verification) 准备(Preparation) 解析(Re ...
- Java面试题:JVM中的类加载机制
JVM 的类加载机制是指 JVM 把描述类的数据从 .class 文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是 JVM 的类加载机制. 类 ...
- 【JVM】虚拟机类加载机制
什么是类加载 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. <[JVM]类文件结构& ...
- jvm之java类加载机制和类加载器(ClassLoader),方法区结构,堆中实例对象结构的详解
一.类加载或类初始化:当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.连接.初始化3个步骤来对该类进行初始化.如果没有意外,JVM将会连续完成3个步骤. 二.类加载时机: 1 ...
- JVM之Java类加载机制
什么是类加载机制 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这既是虚拟机的类加载机制 类的生命周期 生命周期简述 ...
- jvm系列 (五) ---类加载机制
类的加载机制 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 jvm系列 (四) ---强.软.弱.虚引用 我的博客目录 什么是类 ...
随机推荐
- ThinkPHP5使用jwt进行会话验证
以往,没有做过前后端分离的项目之前,都是服务器渲染的模板,然后用cookie和session进行账号的权限验证或者是登录状态的管理.后来接触了vue和小程序之后,在进行前后端分离的时候,就会遇到权限验 ...
- Idea JAVA項目的导入JAR包和导出jar包
一.IDea项目中导入jar包 打开菜单project structure,然后选择modules/dependencies下选择右侧的+,选择jar包目录中的jar文件,导入 二.导出jar包 菜单 ...
- Nginx网络架构实战学习笔记(五):大访问量优化整体思路、ab压力测试及nginx性能统计模块、nginx单机1w并发优化
文章目录 大访问量优化整体思路 ab压力测试及nginx性能统计模块 ab压力测试及nginx性能统计模块 ab压力测试 nginx性能统计模块 nginx单机1w并发优化 整装待发: socket ...
- upc组队赛2 Hakase and Nano【思维博弈】
Hakase and Nano 题目描述 Hakase and Nano are playing an ancient pebble game (pebble is a kind of rock). ...
- PHP定界符<<<的使用方法
在web编程过程中难免会遇到用echo来输出大段的html和javascript脚本的情况,如果用传统的输出方法——按字符串输出的话,使用PHP肯定要有大量的转义符来对字符串中的引号''/" ...
- lg5169 xtq的异或和
题目 根据一些众所周知的结论,我们先跑一棵生成树出来,之后把所有简单环都搞出来,那么\(u\)到\(v\)的路径一定可以由树上的路径和一些简单环拼起来得到 把所有简单环都插到一个线性基里,之后dfs一 ...
- pytest-参数化2
import pytesttest_user_data=['linda','sai','tom']@pytest.fixture(scope='module')def login(request): ...
- ubuntu 设置root密码
- 五分钟学GIS | 快速生成地图瓦片秘籍
什么是地图瓦片? 地图瓦片是包含了一系列比例尺.一定地图范围内的地图切片文件.地图瓦片按照金字塔结构组织,每张瓦片都可通过级别.行列号唯一标记.在平移.缩放地图时,浏览器根据金字塔规则,计算出所需的瓦 ...
- 【知识强化】第五章 输入/输出(I/O)管理 5.2 I/O核心子系统I
学习I/O核心子系统相关的一系列功能. 设备独立性软件.设备驱动程序.中断处理程序这三层其实是属于操作系统的内核部分的,所以它们也称作“I/O核心子系统”,又可以简称为“I/O系统”.在考研当中我们需 ...