jvm概述

作者: 奋斗的韭菜汪 | 来源:发表于2020-08-12 15:13 被阅读0次

    .java文件通过jdk中的javac编译工具编译生成.class字节码文件,.class文件才能被jvm识别运行。
    javac的作用:词法分析->语法分析->生成语法树->生成字节码(.class)
    类加载机制:
    Loading-> Linking->Initializing
    (1)装载(Loading)
    a-通过全路径找到类文件位置(双亲委派)
    b-类文件信息交给jvm
    c-类文件所对应的对象Class交给jvm
    (2)链接(Linking)
    a-验证:验证类文件的语法词法的正确性
    b-准备:为类的静态变量分配内存空间,并将其的值初始化为默认值
    例:static int a=10,会先默认a=0
    c-解析:将类中符号应用转换为直接应用(比如说列字节码文件中的版本信息、类信息、方法信息、接口名...转换成对应的内存地址)
    (3)初始化(Initializing)
    给静态变量赋值 a =10

    双亲委派机制
    定义:如果一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类,而是把 这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以完成类加载任务,就 成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。

    优势:Java类随着加载它的类加载器一起具备了一种带有优先级的层次关系。比如,Java中的Object类,它存放在rt.jar之中,无论哪一个类加载器要加载这个类,最终都是委派给处于模型最顶端的启动类加载器进行加载,因此Object在各种类加载环境中都是同一个类。如果不采用双亲委派模型,那么由各个类加载器自己取加载的话,那么系统中会存在多种不同的Object 类。

    破坏:可以继承ClassLoader类,然后重写其中的loadClass方法,其他方式大家可以自己了解 拓展一下。

    image.png

    方法区(只有一个):存放来自类加载器加载的class文件、常量、静态变量(多线程共享,非线程安全)
    堆(只有一个):存放所有java对象(多线程共享,非线程安全)
    outofmemoryError(方法区和堆内存不足都会导致该错误)
    java虚拟机栈(先进后出)(官方解释):每一个jvm线程都有一个私有的java虚拟机栈,每个线程创建的时候创建虚拟机栈,线程中方法进栈执行,(主要针对java方法)
    本地方法栈(Native Method Stacks):主要针对jvm本地方法的(c或者c++实现的方法)
    程序计数器(pc register):记录线程中方法执行到的位置
    堆和方法区生命周期同虚拟机进程,程序计数器和栈生命周期同线程(线程什么周期很短),所以垃圾回收主要是堆和方法区


    image.png

    栈溢出错误(StackOverflowError)
    编译class文件变成字节码文件:javap -c User.class > User.txt
    iconst_3:将3压入操作数栈中
    istore_0 : 将操作数栈中的3弹出,赋值给局部变量表中的op1
    iload_1:将局部变量1入栈(操作数栈)
    iadd:将操作数栈中两个intzhi弹出并相加然后再入栈

    栈帧(方法):包含局部变量表、操作数栈、动态链接、方法返回地址
    方法中new对象,对象存在堆中,对象的引用存在方法区中
    栈指向堆

    如果在栈帧中有一个变量,类型为引用类型,比如Object obj=new Object(),这时候就是典型的栈中元素指向堆中的对象。
    堆中对象也会指向栈中,比如new user 对重存放了user对象,user对象会指向栈中user类(表明堆中user对象,是user类的对象)

    image.png image.png

    新生代老年代中年龄是指经历垃圾回收的次数,经历过一次垃圾回收标识1岁,对象创建一般是在新生代(young区),但有几种情况对象直接创建在老年代(1、对象特别大(例如新生代100M,老年代300M,创建一个对象110M,则直接在老年代创建),2、新生代年龄到达界限,会移动到old区),
    java中大多数对象都是“朝生夕死”生命周期很短,为什么?
    java多用来做web开发,比如创建订单的一个请求,执行结束order对象就没用了,会被垃圾回收
    新生代young区被分为eden和surviror区,经历垃圾回收没有被回收的少数对象会进入surviror区中(这样就可以保证eden区不会产生大量不连续的空间碎片,大量不连续的空间碎片不能存放稍微大点的对象的情况造成空间浪费)


    image.png

    每次垃圾回收surviror中s0和s1会进行相互转移保证空间连续不出现内存碎片(但是有个弊端,s0和s1总有一个空间为空,有一定的空间浪费),若某一次垃圾回收后s0被占满,没有足够的空间了会向old区借用部分空间(这就是担保机制)

    相关文章

      网友评论

          本文标题:jvm概述

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