JVM 系列(一)类加载

类加载机制是指把 class 文件加载到内存,并对数据进行校验、解析和初始化,最终形成 JVM 可以直接使用的 Java 类型的过程。

ClassLoader 加载一个 class 文件到 JVM 时需要经过以下三个的步骤:

一、加载

将 class 文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时数据构,在堆中生成一个代表这个类的 java.lang.Class 对象,作为方法区类数据的访问入口。

二、链接

将 Java 类的二进制代码合并到 JVM 的运行状态之中的过程。

  1. 验证:确保加载的信息符合 JVM 规范,没有安全方面的问题。

  2. 准备:正式为类变量分配内存空间并设置初始值,常量的赋值也是在这一阶段进行的,这些内存都将在方法区中进行分配。

  3. 解析:虚拟机常量池内的符号引用替换为直接引用的过程。

三、初始化

初始化阶段是执行类构 () 方法的过程。类构造器 () 方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生的。

  1. 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先完成其父类的初始化。

  2. 虚拟机会保证一个类的 () 方法在多程环境中被正确加锁和同步。

  3. 当访问一个 Java 关的静态域时,只有真正声明这个域的类才会被初始化。

四、主动引用和被动引用

那类在什么时候会被初始化呢?

(1) 类的主动引用(一定会发生类的初始化)

  1. new 一个类的对象

  2. 调用类的静态成员(除了 final 常量)和静态方法

  3. 使同 java.lang reflect 包的方法对类进行反射调用

  4. 初始化子类时,要求先会初始化父类

  5. 当虚拟机启动时,先加载含 main() 方法在的类

(2) 类的被动引用(不会发生类的初始化)

  1. 当访问一个静态域时,只有真正声明这个域的类才会初始化

    通过子类引用父类的静量,不会导致子类的初始化

  2. 通过数组定义类引用,不会触发类的初化

  3. 引用常量不会触发类的初始化(常量在编译阶段就存入调用类的常量池中了)

class FinalFieldClass {

    public /*final*/ static String constString = "CONST";

    static {
System.out.println("FinalFieldClass init");
}
} /**
* -XX:+TraceClassLoading
*/
public class UseFinalField {
public static void main(String[] args) {
System.out.println(FinalFieldClass.constString);
}
}

constString 不使用 final 修辞时类 FinalFieldClass 被加载了:

[Loaded com.github.binarylei.jvm.UseFinalField from file:/F:/doc/java/code-2018/disruptor/target/test-classes/]
[Loaded com.github.binarylei.jvm.FinalFieldClass from file:/F:/doc/java/code-2018/disruptor/target/test-classes/]
FinalFieldClass init
CONST

constString 使用 final 修辞时类 FinalFieldClass 没有被加载:

[Loaded com.github.binarylei.jvm.UseFinalField from file:/F:/doc/java/code-2018/disruptor/target/test-classes/]
CONST

参考:

本文转载至《实战JAVA虚拟机 JVM故障诊断与性能优化》


每天用心记录一点点。内容也许不重要,但习惯很重要!

JVM 系列(一)类加载的更多相关文章

  1. jvm系列 (五) ---类加载机制

    类的加载机制 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 jvm系列 (四) ---强.软.弱.虚引用 我的博客目录 什么是类 ...

  2. 【JVM】JVM系列之类加载机制(四)

    一.前言 前面分析了class文件具体含义,接着需要将class文件加载到虚拟机中,这个过程是怎样的呢,下面,我们来仔细分析. 二.什么是类加载机制 把class文件加载到内存,并对数据进行校验.转换 ...

  3. jvm系列四类加载与字节码技术

    四.类加载与字节码技术 1.类文件结构 首先获得.class字节码文件 方法: 在文本文档里写入java代码(文件名与类名一致),将文件类型改为.java java终端中,执行javac X:...\ ...

  4. JVM系列(二)之类加载

    什么是类的加载 类加载是指将源代码编译后的.class加载到内存中初始化待程序使用的过程,类加载的最终结果就是将.class字节码加载到JVM中生成一个java.lang.Class对象,提供给程序使 ...

  5. 从 1 开始学 JVM 系列 | JVM 类加载器(一)

    从 1 开始学 JVM 系列 类加载器,对于很多人来说并不陌生.我自己第一次听到这个概念时觉得有点"高大上",觉得只有深入 JDK 源码才会触碰到 ClassLoader,平时都是 ...

  6. Java虚拟机JVM学习05 类加载器的父委托机制

    Java虚拟机JVM学习05 类加载器的父委托机制 类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap ...

  7. JVM系列五:JVM监测&工具

    JVM系列五:JVM监测&工具[整理中]  http://www.cnblogs.com/redcreen/archive/2011/05/09/2040977.html 前几篇篇文章介绍了介 ...

  8. jvm系列(七):jvm调优-工具篇

    16年的时候花了一些时间整理了一些关于jvm的介绍文章,到现在回顾起来还是一些还没有补充全面,其中就包括如何利用工具来监控调优前后的性能变化.工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗 ...

  9. jvm系列(八):jvm知识点总览-高级Java工程师面试必备

    在江湖中要练就绝世武功必须内外兼备,精妙的招式和深厚的内功,武功的基础是内功.对于武功低(就像江南七怪)的人,招式更重要,因为他们不能靠内功直接去伤人,只能靠招式,利刃上优势来取胜了,但是练到高手之后 ...

随机推荐

  1. os模块和sys模块,以及random模块

    os模块 os模块是与操作系统交互的一个接口 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工 ...

  2. paycharm导入webdriver包报错:module 'selenium.webdriver' has no attribute 'Firefox'

    首先:试试看在cmd中试试输入from selenium import webdriver,看是否报错,看一看是不是pycharm的原因.经过确认,在dos窗口中输入导入包的命令并没有报错.最后我重现 ...

  3. 温故而知新-mysql高级管理

    温故而知新-mysql高级管理 1 mysql的一些授权信息都保存在授权表中 授权表是6个 db,user,host,tables_priv,columns_priv,procs_priv 这6个表 ...

  4. CSS 3栏自适应布局

    绝对定位 css html,body{margin: 0px;height:100%;} div{height: 100%;} .left,.right {top: 0px;position: abs ...

  5. 程序员必看:给你一份详细的Spring Boot知识清单

    在过去两三年的Spring生态圈,最让人兴奋的莫过于Spring Boot框架.或许从命名上就能看出这个框架的设计初衷:快速的启动Spring应用.因而Spring Boot应用本质上就是一个基于Sp ...

  6. windows下的java项目打jar分别编写在windows与linux下运行的脚本( 本人亲测可用!)

    前言: 最近公司做了一个工具,要将这个工具打包成一个可运行的程序,编写start.bat和start.sh在windows和linux下都可以运行. 在网上找了很多资料,最后终于找到一个可靠的资料,记 ...

  7. Tomcat SSL配置及Tomcat CA证书安装

    Tomcat既可以作为独立的Servlet容器,也可以作为其他HTTP服务器附加的Servlet容器.如果Tomcat在非独立模式下工作, 通常不必配置SSL,由它从属的HTTP服务器来实现和客户的S ...

  8. 关于Integer的比较,今天又犯了一个低级错误,记录下

    今天查看以前所写的代码,看到有一部分被人改了,代码如下: if (orgId != organizationUpdateReq.getOrgId()) { //orgId的类型为Integer,org ...

  9. 因为链接服务器 "SQLEHR" 的 OLE DB 访问接口 "SQLNCLI10" 无法启动分布式事务

    1.运行 regedt32,浏览至 HKEY_LOCAL_MACHINE\Software\Microsoft\MSDTC. 添加一个 DWORD 值 TurnOffRpcSecurity,值数据为 ...

  10. COM组件三大接口IUnknown、IClassFactory、IDispatch。

    转自:http://blog.csdn.net/chenyujing1234/article/details/7753863 (1)COM组件有三个最基本的接口类,分别是IUnknown.IClass ...