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系列 (四) ---强.软.弱.虚引用 我的博客目录 什么是类 ...
随机推荐
- php firebase/php-jwt token验证
一:JWT介绍:全称JSON Web Token,基于JSON的开放标准((RFC 7519) ,以token的方式代替传统的Cookie-Session模式,用于各服务器.客户端传递信息签名验证. ...
- python requests函数封装方法
python requests函数封装方法 上代码 import requests import json """ 封装request请求, 1.post:my_pos ...
- Struts1.3——登录案例的改进
在上篇写的用户登录验证案例的基础上进一步改进. 1.在登录成功后的welcome.jsp页面显示登录成功的用户名 思路1:在LoginAction中,将username放入request的域对象中 因 ...
- upc组队赛6 GlitchBot【枚举】
GlitchBot 题目描述 One of our delivery robots is malfunctioning! The job of the robot is simple; it shou ...
- 关于原生js中ie的attacheEvent事件用匿名函数改变this指向后,不能用detachEvent删除绑定事件的解决办法?
博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/28/%e5%85%b3%e4%ba%8e%e5%8e%9f%e7%94%9fjs%e ...
- python基础【第五篇】
python第三节 1.整型及布尔值 1.1 进制转换 十进制 ----二进制 二进制 ----十进制 8421方法与普通计算 python中十进制转二进制示例:bin(51)>>> ...
- opensns学习
根据ThinkPHP官方文档学习opensns框架 主要看了下opensns所用的单一入口模式的意义. 基础 opensns目录结构 index.php 入口文件 Application 应用目录(含 ...
- Web开发进阶
1.可靠性 可扩展性,服务降级,负载均衡 应用扩展 1.垂直扩展,方式:提升机器硬件,缺点,成本昂贵,扩展能力有限 2.水平扩展,方式:增加节点,优点:升级过程平花,硬件成本低,理论上无线扩展,确 ...
- 2018-8-10-win10-uwp-ping
title author date CreateTime categories win10 uwp ping lindexi 2018-08-10 19:17:19 +0800 2018-2-13 1 ...
- sync - 清空文件系统缓冲区
总览 (SYNOPSIS) sync [OPTION] 描述 (DESCRIPTION) 强迫把更改的块写入磁盘, 并更新超级块. --help 显示帮助然后终止. --version 显示版本信息然 ...