zoukankan      html  css  js  c++  java
  • JVM学习一:JVM之类加载器概况

    18年转眼就3月份都快结束了,也就是说一个季度就结束了;而我也因为年前笔记本坏了,今天刚修好了,那么也应该继续学习和博客之旅了。今年的博客之旅,从JVM开始学起,下面我们就言归正传,进入正题。

    一、Java虚拟机与程序的生命周期

    一个运行时的Java虚拟机(JVM)负责运行一个Java程序。
    当启动一个Java程序时,一个虚拟机实例诞生;当程序关闭退出,这个虚拟机实例也就随之消亡.
    如果在同一台计算机上同时运行多个Java程序,将得到多个Java虚拟机实例,每个Java程序都运行于它自己的Java虚拟机实例中。
    在如下几种情况下,Java虚拟机将结束生命周期:
      1.执行了System.exit()方法

      2.程序正常执行结束

      3.程序在执行过程中遇到了异常或错误而异常终止

      4.由于操作系统出现错误而导致Java虚拟机进程终止

    二、类加载器ClassLoader

    上面我们提到了java 程序是基于JVM之上运行的,那么我们知道我们编写的java程序,首先java编译器将我们的源代码编译成为字节码,然后由JVM将字节码load到内存中,接着我们的程序就可以创建对象了,我们知道JVM将字节码load到内存之后将将建立内存模型(JVM的内存模型我们将在稍后阐述),那JVM是怎么将类load到内存中的呢?对了,是通过Classloader;也就是我们说的类加载器。在讲解具体类加载执行流程前,我们来看一段代码:

    class Singleton{
    
        private static Singleton singleton=new Singleton();
    
        private static int counter1;
    
        private static int counter2 = 0;
    
        public Singleton() {
    
           counter1++;
    
           counter2++;
    
        }
    
        public static int getCounter1() {
    
           return counter1;
    
        }
    
        public static int getCounter2() {
    
           return counter2;
    
        }
    
        
        public static Singleton getInstance(){
    
           return singleton;
    
        }
    
    }
    
    
    public class ClassLoaderTest {
    
    
        @SuppressWarnings("static-access")
    
        public static void main(String[] args) {
    
           Singleton singleton=Singleton.getInstance();
    
           System.out.println("counter1:"+singleton.getCounter1());
    
           System.out.println("counter2:"+singleton.getCounter2());
    
        }
    
    }

    我们先猜测一下运行结果,然后我们再来调换一下单实例生成的顺序,将:

    private static Singleton singleton=new Singleton();
    
        private static int counter1;
    
        private static int counter2 = 0;

    修改为:

        private static int counter1;
    
        private static int counter2 = 0;
    
        private static Singleton singleton=new Singleton();

    然后我们会惊奇的发现,竟然结果是不一样的,这又是为什么呢? 学过JVM的的类加载器过程的估计一定知道了,但没有学过的,那么不要急,让我们一起来揭秘。

    三、类的加载流程

    紧接着上面的类型,让我们来看下类加载器到底是如何来加载的,流程如下:

    即类加载经历了:加载 --> 连接 --> 初始化

    1.加载:查找并加载类的二进制数据。

    加载就是将二进制的字节码通过IO输入到JVM中,我们的字节码是存在于硬盘上面的,而所用的类都必须加载到内存中才能运行起来,加载就是通过IO把字节码从硬盘迁移到内存中。

    详细分析见:《JVM学习二:JVM之类加载器之加载分析》:http://www.cnblogs.com/pony1223/p/8641015.html

    2.连接:连接又分为三个步骤:

    验证:确保被加载类的正确性。
    即验证class文件是否符合JVM的要求。
    准备:为类的静态变量分配内存,并将其初始化为默认值。
    解析:把类中的符号引用转换为直接引用。

    详细分析见:《JVM学习三:JVM之类加载器之连接分析》:http://www.cnblogs.com/pony1223/p/8641083.html

    3.初始化:

    为类的静态变量赋予正确的初始值,即在程序里为静态变量指定的初始值,或静态代码块中的赋值操作。
    静态代码块是从上到下顺序执行的,可以对一个静态变量多次赋值,最后的结果为静态变量的初始值。

    详细分析见:《JVM学习四:JVM之类加载器之初始化分析》:http://www.cnblogs.com/pony1223/p/8641181.html

    参考资料:

    圣思园张龙老师深入Java虚拟机系列

  • 相关阅读:
    SmartDb代码修改
    windows下Nginx+RTMP部署
    嵌入式linux下获取flash分区大小
    (转)Qt添加windows开机自启动
    (转)交叉编译lrzsz
    关于海思SDK在Ubuntu下安装错误问题
    电总协议串口调试助手
    使用git将本地仓库上传到远程仓库(转)
    c++中包含string成员的结构体拷贝导致的double free问题
    59. 可变参数
  • 原文地址:https://www.cnblogs.com/pony1223/p/8640448.html
Copyright © 2011-2022 走看看