美文网首页饥人谷技术博客Java
JVM系列之类的使用与卸载

JVM系列之类的使用与卸载

作者: 简楼 | 来源:发表于2021-04-01 22:03 被阅读0次

前言

一个完整即将使用的类已经在JVM虚拟机中整装待发了,进击!!!

类的使用

类的使用一般可以分为主动使用和被动使用;

主动使用

  • 创建类的实例: new关键字、类工厂等
  • 访问某个类或接口的静态变量,或者对该静态变量赋值
  • 调用类的静态方法
  • 反射
  • 初始化一个类的子类
  • main方法
  • 动态语言支持(JDK1.7开始提供)

被动使用

除了以上7种外的所有调用,都是被动调用,都不会对类进行初始化,也就是只会进行类的加载、解析;

案例1

public class Test {
    public static void main(String[] args) {
①------System.out.println(Child.str);  
    }
}
class Parent{
    public static String str = "Parent";
    static {
        System.out.println("Parent 静态代码块");
    }
}
class Child extends Parent{
    public static String str2 = "Child ";
    static {
        System.out.println("Child 静态代码块");
    }
}

输出:

Parent 静态代码块
Parent

将①换成System.out.println(Child.str2)
输出:

Parent 静态代码块
Child 静态代码块
Child 

解析

  • 第一次输出虽然调用了Child.str,但实际上没有对Child进行主动使用,所以不会被初始化,不会输出静态代码块中的内容
  • 第二次输出时,Child是主动使用,Parent因为是Child的父类,所以也初始化,所以子类初始化,父类也会初始化

案例2

public class Test {
    public static void main(String[] args) {
        System.out.println(Parent.uuid);
    }
}
class Parent {
    public static final String uuid= UUID.randomUUID().toString();
    static {
        System.out.println("parent4 static block");
    }
}

解析

uuid是静态常量,但是在编译期uuid的值并不能确定,这个值就不会被放到常量池中,所以这个类的初始化会在被主动调用时触发。

总结

  • 类的初始化一定是首次、主动使用该类
  • 子类初始化,父类也会初始化,并且父类先初始化完毕(不适用于接口)
  • final修饰的常量,在编译阶段,就会被放在调用这个常量的方法的所在的类的常量池,调用类并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化;如果final定义的值随机产生或每次都会改变,则该值不会放入调用它的方法的常量池中,所以每次调用依旧触发该对象所在的类(主动使用),该类即被初始化
  • 当一个接口在初始化时,并不要求其父接口完成了初始化,只有在真正使用到父类接口的时候(如引用接口中定义的常量时),父类才会被初始化

常用java虚拟机参数(类加载/卸载跟踪)

-verbose:class 跟踪类的加载和卸载
-XX:+TraceClassLoading 跟踪类的加载
-XX:+TraceClassUnloading 跟踪类的卸载

-XX:+PrintClassHistogram 查看系统中类的分布情况
(需要在控制台按下Ctrl+Break组合键,就会出现柱状图,可以看到当前系统中占用空间最多的对象,以及其实例数量和空间大小 )

相关文章

  • JVM系列之类的使用与卸载

    前言 一个完整即将使用的类已经在JVM虚拟机中整装待发了,进击!!! 类的使用 类的使用一般可以分为主动使用和被动...

  • JVM系列之类的准备与解析

    一、前言 每个类的生命周期,和生命一样,都有起点与终点;每个类都会在自己的生命周期里,完成自己的使命--使命必达!...

  • JVM系列之类的加载

    一、前言 一处编译,处处运行! 二、JVM是什么? JDK包含了JRE,JRE是java程序的运行环境; JDK:...

  • JVM系列之类的验证

    一、前言 类的加载完成后,就是验证;保加载进来的字节流符合JVM规范 二、验证三问 1)什么是验证? 验证.c...

  • jvm系列之类加载机制

    muggle 1.类的生命周期    类从被加载到虚拟机内存中内存中开始,到卸载出内存为止,它的整个生命周期包括:...

  • JVM介绍系列文章

    知晓JVM系列(一):对JVM总览知晓JVM系列(二):JVM内存管理机制与优化初探知晓JVM系列(三) :常用的...

  • JVM

    简介 Jvm 系列一:Java类的加载机制Jvm系列二:JVM内存结构 --内存泄漏与内存溢出Jvm系列三:GC算...

  • JVM

    JVM之内存模型JVM之对象定位与访问JVM之Java垃圾回收机制JVM之类加载

  • JVM系列之类的初始化

    类的初始化 前言 类孕育了新的生命周期,那么接下来就是让他健康的茁壮成长,对否? 案例1 输出值: 案例2 输出值...

  • JVM 之类加载

    一.概述 Java不同于C/C++这类传统的编译型语言,也不同于php这一类动态的脚本语言。可以说Java是一种半...

网友评论

    本文标题:JVM系列之类的使用与卸载

    本文链接:https://www.haomeiwen.com/subject/lnsxkltx.html