过程

装载

条件

主动使用 class时

  • 创建一个类的实例 (new 、反射、克隆、反序列化)
  • 调用类的静态方法(invokestatic)
  • 使用类或接口的静态字段(getstatic、putstatic)
  • 使用 reflect反射
  • 初始化子类,先初始化父类
  • main方法的类

例子

被动引用不会初始化类

package com.mousycoder.mycode.thinking_in_jvm;

/**
* @version 1.0
* @author: mousycoder
* @date: 2019-09-02 16:29
*/
public class Parent {
static {
System.out.println("Parent init");
}
public static int v = 100;
} package com.mousycoder.mycode.thinking_in_jvm; import sun.jvm.hotspot.memory.ParNewGeneration; /**
* @version 1.0
* @author: mousycoder
* @date: 2019-09-02 16:29
*/
public class Child extends Parent { static {
System.out.println("Child init");
}
} package com.mousycoder.mycode.thinking_in_jvm; /**
* @version 1.0
* @author: mousycoder
* @date: 2019-09-02 16:32
*/
public class UseParent {
public static void main(String[] args) {
System.out.println(Child.v);
}
}

虚拟机参数 -XX:+TraceClassLoading

输出

[Loaded com.mousycoder.mycode.thinking_in_jvm.Parent from file:/Users/mousycoder/My/code/mycode/target/classes/]
[Loaded com.mousycoder.mycode.thinking_in_jvm.Child from file:/Users/mousycoder/My/code/mycode/target/classes/]
Parent init
100
[Loaded java.lang.Shutdown from /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/rt.jar]
[Loaded java.lang.Shutdown$Lock from /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/rt.jar]

表示 Child被加载了,但是没有被初始化

final 常量不会引起类初始化

package com.mousycoder.mycode.thinking_in_jvm;

/**
* @version 1.0
* @author: mousycoder
* @date: 2019-09-02 16:41
*/
public class FinalFieldClass { public static final String constString = "CONST";
static {
System.out.println("FinalFieldClass init");
} }
package com.mousycoder.mycode.thinking_in_jvm; public class UseFinalField {
public static void main(String[] args) {
System.out.println(FinalFieldClass.constString);
}
}

输出

CONST

FinalFieldClass 类没有因为常量 constString 被引用而初始化,而是直接把CONST 放在常量池中



加载

例子:加载String类

package com.mousycoder.mycode.thinking_in_jvm;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier; /**
* @version 1.0
* @author: mousycoder
* @date: 2019-09-03 13:38
*/
public class StringTest {
public static void main(String[] args) throws ClassNotFoundException {
Class clzStr = Class.forName("java.lang.String");
Method[] ms = clzStr.getDeclaredMethods();
for (Method m : ms) {
String mod = Modifier.toString(m.getModifiers());
System.out.println(mod + " " + m.getName() + " ( ");
Class<?>[] ps = m.getParameterTypes();
if (ps.length == 0 ){
System.out.println(')');
}
for (int i = 0; i < ps.length; i++) {
char end =i==ps.length-1 ? ')':',';
System.out.println(ps[i].getSimpleName() + end);
}
System.out.println();
}
}
}

输出

``

public equals (

Object)

public toString (

)

public hashCode (

)

public volatile compareTo (

Object)

public compareTo (

String)

public indexOf (

String,

int)`

``

验证

保证加载的字节码合法

准备

为类分配对应的内存空间,并设置初始值,此阶段不会有 java 代码执行

类型 默认初始值
int 0
long 0L
short (short)0
char \u0000
boolean false
reference null
float 0f
double 0f

解析

将类、接口、字段、方法的符号引用(字面量的引用)转成直接引用(找到方法中表的位置)

初始化

执行类的初始化方法,此方法由编译器自动生成的,由类静态成员的赋值语句以及static 语句块合并产生

其中函数是带锁线程安全的,可能会导致死锁。

【深入浅出-JVM】(75):class 装载的更多相关文章

  1. 深入浅出 JVM GC(3)

    # 前言 在 深入浅出 JVM GC(2) 中,我们介绍了一些 GC 算法,GC 名词,同时也留下了一个问题,就是每个 GC 收集器的具体作用.有哪些 GC 收集器呢? Serial 串行收集器(只适 ...

  2. 深入浅出 JVM GC(2)

    # 前言 在 深入浅出 JVM GC(1) 中,限于上篇文章的篇幅,我们留下了一个问题 : 如何回收? 这篇文章将重点讲述这个问题. 在上篇文章中,我们也列出了一些大纲,今天我们就按照那个大纲来逐个讲 ...

  3. 阿里架构师带你深入浅出jvm

    本文跟大家聊聊JVM的内部结构,从组件中的多线程处理,JVM系统线程,局部变量数组等方面进行解析 JVM JVM = 类加载器(classloader) + 执行引擎(execution engine ...

  4. 深入浅出 JVM ClassLoader

    # 前言 在 JVM 综述里面,我们说,JVM 做了三件事情,Java 程序的内存管理, Java Class 二进制字节流的加载(ClassLoader),Java 程序的执行(执行引擎).我们也说 ...

  5. 对JVM还有什么不懂的?一文章带你深入浅出JVM!

    本文跟大家聊聊JVM的内部结构,从组件中的多线程处理,JVM系统线程,局部变量数组等方面进行解析 JVM JVM = 类加载器(classloader) + 执行引擎(execution engine ...

  6. 【深入浅出-JVM】(77):SPI

    概念 Service Provider Interface 规则 在resource/META-INF/services 创建一个以接口全限定名为命名的文件,内容写上实现类的全限定名 接口实现类在cl ...

  7. JVM的类装载子系统

    在JAVA虚拟机中,负责查找并装载类型的那部分被称为类装载子系统. JAVA虚拟机有两种类装载器:启动类装载器和用户自定义类装载器.前者是JAVA虚拟机实现的一部分,后者则是Java程序的一部分.由不 ...

  8. 深入浅出 JVM GC(4)常用 GC 参数介绍

    # 前言 从前面的3篇文章中,我们分析了5个垃圾收集器,还有一些 GC 的算法,那么,在 GC 调优中,我们肯定会先判断哪里出现的问题,然后再根据出现的问题进行调优,而调优的手段就是 JVM 提供给我 ...

  9. 深入浅出 JVM GC(1)

    # 前言 初级 Java 程序员步入中级程序员的有一个无法绕过的阶段------GC(Garbage Collection).作为 Java 程序员,说实话,很幸福,不用像 C 程序员那样,时刻关心着 ...

随机推荐

  1. maven的不同版本下载及环境配置

    Maven不同版本下载及环境配置 Maven下载 去到官网 https://maven.apache.org/ 会发现是最新版本,但是一般下载的话,都会下载比最新的版本要低两到三个小版本的,这里就下载 ...

  2. 为什么双重检查锁模式需要 volatile ?

    双重检查锁定(Double check locked)模式经常会出现在一些框架源码中,目的是为了延迟初始化变量.这个模式还可以用来创建单例.下面来看一个 Spring 中双重检查锁定的例子. 这个例子 ...

  3. Statement和PreparedStatement

    Statement与PreparedStatement的关系和区别: 关系:PreparedStatement继承自Statement,都是接口. 区别:PreparedStatement可以使用占位 ...

  4. 编程使用c#连接到IBM db2的两种方式

    一:使用c#通过odbc连接到IBM db2使用 ConnectionString 属性连接到各种数据源. 部署:只要在客户端安装IBM DB2 ODBC driver.配置DSn即可. 1):可以单 ...

  5. Java反射Reflect的使用详解

    目录 一. 什么是反射 二. 反射的基础Class 2.1 Class类概述 2.2 Class类对象获取的三种方式 三. 反射-构造函数 3.1 getDeclaredConstructor(Cla ...

  6. K8S搭建-1 Master 2 Workers(dashboard+ingress)

    本文讲述k8s最新版的搭建(v1.15.2) 分如下几个topic步骤: 各个节点的基本配置 master节点的构建 worker节点的构建 安装dashboard 安装ingress 常见命令 do ...

  7. 《Java 8 in Action》Chapter 2:通过行为参数化传递代码

    你将了解行为参数化,这是Java 8非常依赖的一种软件开发模式,也是引入 Lambda表达式的主要原因.行为参数化就是可以帮助你处理频繁变更的需求的一种软件开发模式.一言以蔽之,它意味 着拿出一个代码 ...

  8. 你真的了解setState()吗?

    React 中 setState()详细解读 对于 setState() 相信伙伴们都用过,它是 React 官方推荐用来更新组件 state 的 API,但是对于 setState() 你真的了解吗 ...

  9. unity之加载场景

    游戏中的Loading分为:静态Loading和动态Loading. 简单形象的做个比喻: 静态Loading可能就是一张背景图.而动态的Loading就是在读取的同时有一个东西在“转圈”. 1.静态 ...

  10. Leetcode之回溯法专题-40. 组合总和 II(Combination Sum II)

    Leetcode之回溯法专题-40. 组合总和 II(Combination Sum II) 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使 ...