走进JVM,浅水也能捉鱼!
这不是一篇描述jvm是什么的文章,也不介绍jvm跨平台的特性,也不是讲述jvm安全特性的文章,更不是讲解jvm指令操作,数据运算的文章, 本文重点讲述 类型的生命周期.
类型的生命周期涉及到: 类的装载、jvm体系结构、垃圾回收机制.
为什么要讲jvm体系结构? 因为类的装载和垃圾回收机制都和jvm体系结构息息相关.
那么什么是jvm体系结构呢?
当jvm运行起来的时候,它会向系统申请一片内存区(不同的jvm实现可能不同,有些可以使用虚拟内存),将这块内存分出一部分存储许多东西,例如:程序创建的对象,传递给方法的参数,返回值,局部变量等等,我们将这块内存称之为"运行时数据区", 运行时数据区可以划分成方法区、堆、java栈、pc寄存器、本地方法栈.
看到上面这幅图,和这些解说你可能大概的明白jvm 体系是个啥样子,但是你或许还不了解运行时数据区里面方法区等用来干嘛的.
方法区:当虚拟机装载一个class文件的时候,它会从这个class文件包含的二进制数据中解析类型信息.然这些类型信息放到方法区中.因为方法区是被所有线程共享的,所以必须考虑数据的线程安全.假如两个线程都在试图找lava的类,在lava类还没有被加载的情况下,只应该有一个线程去加载,而另一个线程等待.
Pc寄存器:每个新线程产生都将得到自己的pc寄存器以及一个java栈帧.
堆:存放程序运行时产生的所有对象.堆是一个线程共享的内存区,所以我们写多线程程序的时候需要考虑并发.
Java栈:java栈由许多栈帧组成的,如图,当一个线程调用java方法时,虚拟机压入一个新的栈帧到java栈中,当方法返回的时候,这个栈帧被从java栈弹出并被抛弃.
那么现在你应该可以想象到一些jvm是怎么工作的了,是不是应该接着讲具体工作原理了呢?.但是不急,先了解下类的装载机制.
了解类的装载机制之前先了解jvm里面的类装载器:Bootstrap Loader、ExtClassLoader 、AppClassLoader;
ExtClassLoader (负责装载jre下面的rt.jar, charsets.jar)和AppClassLoader(负责转载classpath下面的类包)是ClassLoader(抽象类)的子类;
Bootstrap Loader(负责装载jre核心类库)是根装载器是c/c++写的在java里面看不到它.
这三个类装载器存在父子关系, 根装载器是 ExtClassLoader父装载器,ExtClassLoader是AppClassLoader父装载器;
Jvm中类的装载也是安全机制沙箱模型的第一道门槛. Java装载类使用"双亲委派模式"-即全盘负责委托机制.