JVM虚拟机原理

JVM虚拟机原理

黄色部分是线程共享的     每个线程对应一个栈

我们的通过编译生成的.class文件,知道你的类名以后,通过classLoader首先把类加载到方法区里面,首先我們要知道,lei类加载它并不是实例化的过程,类加载时把类放到jvm的过程,而不是创建对象的过程,创建对象的过程涉及到栈区里面方法执行的过程,这是方法在执行过程用到那个类就去加载哪个类,

JVM虚拟机原理很多人不知道这个类是怎么被加载的即我圈的CC那个类,

当你运行java程序的时候,你在dos里运行时肯定要输入java  com.changchang.cn.CC  肯定会指定这个类名的,类加载器首先就会把这个CC类加载进method area 里面,但是你要记得 在启动虚拟机的时候就把java核心类库(rt.jar)全部都加载进来了,

JVM虚拟机原理

在执行main的时候,碰到没有被加载的类,就看下方法区有没有,如果没有就加载到方法区

类加载器的分类:Bootstrap类加载器,ExtClassLoader,AppClassLoader 每种加载器都设定好从哪里加载类

BootstrapClassLoader--------->JRE/lib/rt.jar

ExtClassLoader-------->JRE/lib/ext或者


AppClassLoader ------>CLASSPATH环境变量,由classpath或-cp选项定义

类加载器的工作原理有1.委托机制,加入你要加载Person.class这个类,首先加载这个类的请求由AppClassLoader 委托给它的父类ExtClassLoader,然后再委托给BootstrapClassLoader,BootstrapClassLoader先看看rt.jar里面有没有这个类,如果没有,就返回给ExtClassLoader 查看jre/lib/ext目录下有没有这个类,如果还没有就由AppClassLoader   从classpath中寻找, 记住

classpath定义的是类文件的加载目录,而PATH定义的是可执行程序如javac java等的执行路径

2.可见性机制,子类加载器可以看到父类加载器加载的类,而反之则不行,如果ABC.class已经被AppClassLoader 加载过了,再用

ExtClassLoader的话就会抛出java,lang.ClassNotFountException

JVM虚拟机原理


3.单一性:父类加载器加载过的类不能被子类加载器加载第二次




由于方法区里面存放的是类类型(Class),运行时加载类是你用到哪个类先去method area区找如果没有,你就把他加载进来存进方法区,你想呀 我们从main方法进去的时候肯定会遇见没有加载过的类,jam发现这个类没有被加载,就开始查找某某类.class文件,从类文件中抽取类型信息并放在了方法区 ,这个类一旦被加载,它就常驻内存里面了,

方法区溢出是加载太多导致的,堆溢出是加载对象太多导致的      栈溢出是方法太多导致的,如方法的死递归

类型信息:

对于每个加载的类型,jvm必须在方法区存储以下类型信息: 

方法区是线程共享的,当两个线程同时要加载一个类型的时候,只有一个类会请求Classloader加载,另一个线程会等待。

1:这个类型的完整有效名

2.这个类型直接父类的完整有效名(除非这个类是interface或者是java.lang.Object,这两种情况都没有父类

3.这个类型的修饰符(public,abstract,final)

4.即时编译后的代码等信息

除了这些基本信息外,jvm还要为每个类型保存一下信息:

类型的常量池:

field信息

方法信息

所有static变量 ,在这里提一点就是可以把全局变量放在静态代码块里面,


在这之前先讲一下Class这个类的概念

                           class Person{

                            }这里有个Person类,这个类的实例对象如何表示呢?下面这句话就是了

                          Person   p   =     new Person();    p就是Person这个类的实例对象,

                        class Student{

                            }

                         Student student = new Student();    student就是Student这个类的实例对象,

由于java里面万事万物皆对象  这个Person,Student类 也是一个实例对象,它是大写Class类的实例对象 ,也就是说我们平常所见到的类都是Class的实例对象   那么改如何表示呢?有三种表示方法:我们就举上面的Person类吧


JVM虚拟机原理

    1:Class c1 = Person.class(即类名.class)

    2:  Class c2 = p.getClass(即对象.getClass)    这里的p是 大写Person类的实例对象

 写到这里可能你们会有些混淆:我再重申一下  上面的 p是Person类的实例对象,c1 c2代表 Class类的实例对象,

但是这个c1实例对象说的是什么玩意呢,说的是Person这个类本身就是一个实例对象

官网给出的准确说法是: c1 c2是 Person类的类类型(class type) ,类的类类型怎么理解呢,你就这样理解,Person类本身就是Class类的一个实例对象 ,你要清楚一点Person这个类本身也有实例对象,就是p, 我们以后就可以这么叫了 p是Person类的实例对象,c1是Person类的类类型

    3:c3=Class.forName("类的路径");      这里c1==c2==c3的

我们完全可以通过类的类类型创建该类的实例--->通过c1,c2,c3创建Person类的实例对象  

如果是Person类的类类型,创建出来的是Person对象,如果是Student类的类类型,创建出来的是Student对象,所以要进行强转

即:Person person=(Person)c1.newInstance();   这里newInstance前提是要有要有无参构造的


上面讲到的Class.forName(); 不仅表示了类的类类型,还代表了动态加载类,大家要区分编译和运行,

编译时刻加载类是静态加载类,运行时刻加载类是动态加载类,这里说下静态加载类

我们在dos里面输入 javac Office.java  来进行编译,会报错,因为缺少Word类跟Excel类

JVM虚拟机原理

我们如果建一个Word类,然后 进行编译后,再去编译javac.Office.java就会报只缺少Excel这个类的错误了,在这里我们已经建好了Word类,想用却因为没有Excel类的原因用不了,这显然不是我们想要的,我们要的是,我建一个Word类我就能用,大家想想,如果程序里有100个类,有一个用不了其余的99都用不了的话你将会有多么的崩溃呀,这就是静态加载类的弊端,new创建对象是静态加载类,在编译的时候就需要加载所有可能使用到的类,不管你用不用,

 通过动态加载类我们可以解决此问题,Class.forName,就是动态加载类,就不会在编译时候报错了,它只会在你用到这个类的时候才会报没有类的错误,




 java虚拟机栈就是java方法执行的内存模型,每调用一个方法,就会生成一个栈帧 用于存储方法的本地变量表,方法出口等信息

每次方法的调用都会对应栈帧的压栈跟出栈,如果请求的栈的深度过大,就会抛出stackOverflowError

JVM虚拟机原理


JVM虚拟机原理JVM虚拟机原理



热部署其实是也可以通过java的热加载来实现的

JVM虚拟机原理

上面这个图的准备阶段做一下描述,假如说private static int num=80; 在这个准备阶段,它并不是把这个num初始化成为80 ,而是赋初始值,int类型的初始值为所以准备阶段是num的值是0,初始化阶段num的值才为80

什么时候初始化呢,5个初始化的时机,

需要先触发类初始化(加载-验证-准备自然需要在此之前): 
1)1.使用 new 关键字实例化对象 2.读取或设置一个类的静态字段 3.调用一个类的静态方法。 
2)使用 java.lang.reflect 包的方法对类进行反射调用时,若类没有进行初始化,则需要触发其初始化 
3)当初始化一个类时,若发现其父类还没有进行初始化,则要先触发其父类的初始化。 
4)当虚拟机启动时,用户需要制定一个要执行的主类(有 main 方法的那个类),虚拟机会先初始化这个类。

final  修饰的类会在编译期的时候把结果放在常量池,即使调用也不会触发初始化  ,final修饰的是个常量,它会把常量放在常量池中,调用常量它不会出发初始化的这个阶段 



       

相关文章:

  • 2021-04-06
  • 2021-08-16
  • 2022-01-19
  • 2021-10-24
  • 2021-11-23
  • 2022-01-14
  • 2021-11-23
  • 2021-11-23
猜你喜欢
  • 2021-12-09
  • 2021-06-14
  • 2021-11-23
  • 2021-10-31
  • 2021-10-14
相关资源
相似解决方案