1.JVM运行机制的整体脉络

JVM系列

1.JVM运行机制的整体脉络
2.JVM的分代模型及对象流动
3.常见的垃圾回收器及算法
4.ParNew和CMS的工作原理

1.JAVA代码是怎么运行?

实例代码,创建一个Test类 ,如下:

public class Test {
  public static void main(String[] args) {
   system.out.println("hello world!");
  }
}

要运行代码经过的流程:Test.java编译->Test.class->类加载器->JVM->代码执行。如下图1-1:

1-1.png

2.类是如何加载,何时加载?
  • 一个从加载到使用一般会经历如下过程:
    加载->验证->准备->解析->初始化->使用->卸载
  • 什么时候会加载一个类:
    举个例子,改动上面代码,如下:
public class Test {
  public static void main(String[] args) {
     User user = new User();
     system.out.println("hello world!");
  }
}

public class User {
    String name;
    //set get方法省略
}

程序启动的时候会去加载带main方法的Test.class,当执行main方法,发现需要用到User.class,然后就去加载。所以当用到的时候才会加载一个类,如下图1-2:

1-2.png

3.关于验证,准备,解析,初始化
  • 验证阶段:校验加载到内存的".class"文件是否符合JVM规范,防止被人修改过,符合才交给JVM。
  • 准备阶段:为class开避内存空间,对类变量(static修饰的变量)赋默认值,比如int类型的则赋值0。
  • 解析阶段:虚拟机将常量池内的符号引用替换为直接引用的过程。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。
  • 初始化阶段:执行class的初始化代码,比如一些静态变量的赋值,静态代码块。
    注意 当我们初始化一个类的时候,如果它的父类还没初始化,会先初始化父类。
4.类的加载机制?
  • 类的加载器
    1.启动加载器(BootStrap ClassLoader):主要加载Java安装目录(lib)下的核心类库。
    2.扩展类加载器(Extension ClassLoader):主要加载Java安装目录(lib/ext)下的扩展类库。
    3.应用加载器(Application ClassLoader): 负责加载指定Classpath环境下的类,就是我们写好的java代码。
    4.自定义加载器:跟据特定的需求可以自己自定义类加载器,加载特定目录的类。
    5.类加载器的继承关系,如下图1-3:
    1-3.png
  • 双亲委派机制
    原理:当需要加载一个类的时候,当前加载器会委托他的父亲加载,这样一层一层往上抛,抛到最上层,如果父亲加载不了,则往下传,让下面的子类加载,直至到当前类加载器。
    为什么要这样:考虑安全因素,以防止核心API库被随意篡改,试想一下,如果我们自己写了一个java.lang.Object类替换掉jdk里面的,被系统加载了,这会产生很大的问题。
    总结:先让父亲加载,加载不了再由儿子加载。大致流程如下图1-4:
    1-4.png
5.JVM有哪些内存区域,都有什么用?
  • :存放实例对象。比如代码new User(),创建的对象就放在堆里面。
  • 方法区:存放从".class"文件加载上来的类和一些静态变量。
  • 虚拟机栈:存放线程执行方法时的信息,比如方法名,方法变量信息等。
  • 程序计数器:记录每个线程执行代码的位置。
  • 本地方法栈:存放native方法执行时的信息。
    用如下代码,从加载到执行,所使用到的内存区域流程图1-5:
public class Test {
  public static void main(String[] args) {
     User user = new User();
     system.out.println("hello world!");
  }
}

public class User {
    String name;
    //set get方法省略
}
1-5.png
6.为什么会有垃圾回收机制?

如上面的图片,JVM的内存是有限的,程序一直在运行,那么当一个方法执行完成后会怎样?方法会出栈,直接释放内存。但是方法执行期间创建的对象怎么办,现在没有引用它,但它还占用着内存。当越来越多的对象创建,内存很快就不够,那么这时个就需要一个办法把没用的对象清空,释放内存。垃圾回收器就是干这个事情的。当达到一定条件时,会触发垃圾回收。如下图1-6:

1-6.png

你可能感兴趣的:(1.JVM运行机制的整体脉络)