美文网首页
一篇文章详解JVM

一篇文章详解JVM

作者: zain丶月下 | 来源:发表于2020-02-02 17:52 被阅读0次

    在学习Java中,JVM到底是什么呢?可能带有很多的疑问。在这里给大家详细的讲解一下什么是JVM。这个也是小编在最近自己学习总结。

    1、什么是JVM

    JVM是Java Virtual Machine(Java[虚拟机])的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。java常见三种JVM:HotSpot,JRockit,j9vm

    查看本地jvm

    2、JVM在什么位置

    先给大家看一张关于jvm图


    jvm位置.png

    在JVM中,我们可以看到JVM处于操作系统之上。老师在教我们编写第一行代码的时候,就先教我们安装环境。在图中我们可以看到。平时我们开发的软件都是基于jvm的环境上运行的。

    3、class类运行执行过程

    在给大家看一张关于jvm的图片


    java文件执行过程

    这张图对于学习java的人应该很熟悉。这就是完整的.java文件运行的过程



    在这里我们可以看到运行时数据区中。各个模块的执行具体细节。
    1. 类加载器
      顾名思义类加载器就是加载class类。在类加载器中


      类加载器

      平时我们为什么能够得到类。是由于类加载器的作用


      类加载器.png
    测试.png
    代码中我们可以看到。得到类的加载器时,先查找本地系统的类加载器,如果没有就向上一层查看。直到最后根系统加载器。这就是双亲委派机制。
    双亲委派机制:主要是保证类的安全,所有的类,加载的时候,都会先委托父类,直到最顶层,如果有这个类,就直接加载顶层的这个类如果没有,就向下找,直到找到位置。
    1. 本地方法栈
      JVM调用本地方法
      在本地库接口中,本地方法接口JNI(Java Native Interface)。 java本地方法接口凡是带了native关键字,说明java程序触及不到,就会进入本地方法栈。本地方法栈中即可调用本地方法接口中的接口
    2. 虚拟机栈
      存放方法运行时所需的数据,成为栈帧。
    public class TestDemo2 {
        public static void main(String[] args) {
            test();
        }
        public static void test() {
            System.out.println("1");
        }
    }
    

    在上面的例子中,就是一个压栈的过程

    栈和队列
    栈(数据结构):先进后出,后进先出
    队列:先进先出
    在这里借用老师的一句话:喝多了吐就是栈,吃多了拉就是队列
    如果在压栈的过程中出现了无限压栈会有什么情况呢?

    image.png
    这就是我们常说的栈溢出:java.lang.StackOverflowError
    而压栈过程就如下图
    栈帧

    1. 用于存储对象实例,在讲解堆时要联合方法区和栈一起讲解


      堆,栈,方法区

      在我们new对象时,我们会产生一个对象。就会存在一个压栈的过程和调用对象的实例的过程

    注意:
    (1) 基本数据类型的存储原理:所有的简单数据类型不存在“引用”的概念,基本数据类型都是直接存储在内存中的内存栈上的,数据本身的值就是存储在栈空间里面,Java语言里面八种数据类型是这种存储模型;

    (2) 引用类型的存储原理:引用类型继承于Object类(也是引用类型)都是按照Java里面存储对象的内存模型来进行数据存储的,使用Java内存堆和内存栈来进行这种类型的数据存储,简单地讲,“引用”(存储对象在内存堆上的地址)是存储在有序的内存栈上的,而对象本身的值存储在内存堆上的;

    1. 方法区
      存储运行时常量池,已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据

    4、GC垃圾回收

    在讲解GC时,应该理解GC发生在什么地方。我们常说的GC100%发生在数据共享区,也就是方法区和堆。而百分之99%的GC又发生在堆中。

    4.1 GC中的分区
    1. 次数最频繁:Young区
    2. 次数较少:old区(Young区常用的放入old区)
    3. 基本不动:perm永久区


      GC
    4.2 GC中的算法
    1. 引用计数法
      引用计数法
      在引用计数法:当赋值对象时,就给对象一个标识,如果之前这个对象在引用则加一,当为零时及未引用。 清除为零的对象。即按照是否引用进行清除
      缺点:循环引用时,无法清除(对象1引用对象2,对象2引用对象1,则一直会引用)。所以JVM一般不用这个方法
    2. 复制算法
      复制算法
      在Eden区,存放所有的数据,经过GC清理,复制到to区,from区的数据也会复制到to区。清空from区。并且from变为to区。之前的to区变为了from区。当Young区满了后,就会引发一次轻GC。 如果在引用Young区的数据超过5次。则会把数据放入old区(常用)。如果old区站满。则会引发一次重GC。当Young区和old区都满了后。就会引发OOM。
      缺点:内存空间多浪费一半,需要双倍的空间
      极端情况:当数据100%需要清理时,浪费时间。假设在一片区域对象存活极低,则复制算法实用。结论表明:99%的会被GC回收
      优点:不会存在内存的碎片
    3. 标记清除
      标记清除
      3.1 在未引用的数据上面。给一个标记。
      3.2 清除标记后的数据。
      缺点:二次扫描数据,会产生内存碎片(清理不连续)
    4. 标记压缩(整理)
      标记压缩
      缺点:移动标记清除后的数据需要成本
      优点:把标记清除后的数据压缩到一起。就不会产生垃圾碎片。
    在所有的算法中?难道没有最优的算法嘛?

    没有最优的算法。只有最合适的算法。比如在Young区采用复制算法。在old区采用标记压缩方法。这种在不同区域引用不同的算法叫:分带收集算法

    相关文章

      网友评论

          本文标题:一篇文章详解JVM

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