JVM(下)

四、本地方法接口

        一、概念

        二、使用原因

五、执行引擎

        一、概述

        二、解释器、JIT编译器

        三、Java是半编译半解释型语言

六、垃圾回收

        一、概述

        二、相关算法

        三、相关概念

        四、垃圾回收器

四、本地方法接口

        一、概念

        被关键字 native修饰的方法,不是Java语言实现的,而是由操作系统实现的方法。

        二、使用原因

        因为上层高级语言没有对底层硬件直接操作的权限,而是需要调用操作系统提供的接口进行访问。

五、执行引擎

        一、概述

        负责将装到虚拟机中的字节码再编译成机器码,是JVM 的核心组成部分。

        二、解释器、JIT编译器

        解释执行:对字节码采用逐行解释的方式执行,例如脚本语言,python,css,js,html。

其特点是效率低但是省去了编译时间。

        编译执行:把某段代码进行整体编译,执行编译后结果。其特点是效率高但需要编译时间。

        三、Java是半编译半解释型语言

        将字节码转换成机器码。

        程序刚开始运行时,采用逐行解释执行。

        程序运行过程中,将热点代码编译并执行起来。

        这样结合起来使用,提高运行效率。

六、垃圾回收

        一、概述
        1、垃圾

        一个没有被任何引用所指向的对象。这个对象就是垃圾对象。

        垃圾对象需要被回收清理,否则一致占用内存空间,其他新对象无法使用垃圾对象占用空间,严重的话会造成内存溢出。

        2、早期垃圾回收。

        早期C++/C语言时代,垃圾回收都是程序员手动在程序不再使用的对象进行删除释放,给程序员造成了繁重工作量,万一忘记回收,会造成内存泄漏。

        3、垃圾回收区域。

        堆占比较多其中新生代占比多,老年代占比少。

        方法区占比较少。

        二、相关算法
        标记阶段:

        标记出哪些对象是垃圾对象。

        引用计数算法:

        在对象中有一个技术属性,只要有引用指向对象计数器+1,计数器值为0,则此对象是垃圾对象,算法实现简单。

        缺点:计数器占用空间,加一减一需要时间开销,无法解决循环引用。

        可达性分析算法(根搜索算法):

        从一些活跃对象(GCRoot)开始搜索,与根对象相关联的对象都是被使用的,与根对象或根对象相关的引用链不相关的对象就是垃圾对象。

        GCRoot可以是:

        1.虚拟栈中(正在运行方法)被引用对象;

        2.类中静态属性;

        3.被用来当作同步锁;

        4.Java系统中的类。

JVM(下)_第1张图片

   对象的 finalization 机制

        finalize() 方法是在对象被回收前,在此方法中执行一些需要的逻辑。

Object中的方法,protected void finalize() throws Throwable { }。

        当对象被判定为垃圾对象,在回收之前会调用 finalize(),且只能调用一次

        永远不要主动调用 finalize()方法,交给垃圾回收机制调用。

        1.在 finalize()时可能会导致对象复活。

        2.finalize()方法的执行时间是没有保障的,它完全由 GC 线程决定,极端情况下, 若不发生 GC,则 finalize()方法将没有执行机会。

        3.一个糟糕的 finalize()会严重影响 GC 的性能。比如 finalize 是个死循环。

由于 finalize()方法的存在,虚拟机中的对象一般处于三种可能的状态

        可触及:不是垃圾对象。

        可复活:被标记为垃圾对象,但 finalize()没有被调用。

        不可触及:被标记为垃圾对象,finalize()已经被调用。

    回收阶段:

        标记--复制算法:

        可以有多块内存,每次有一块是空闲的。

        将存活的对象移动到未使用的空间中,清除其他块中所有的垃圾对象。

         好处:内存碎片少。

        适合:存活量小的垃圾对象多的区间(新生代回收)。

        标记--清除算法:

        存活对象位置不变,将垃圾对象地址记录在一个空闲表上,后面如果创建新对象,就会将空闲列表中垃圾对象覆盖掉。

        特点:不移动对象,回收后会产生内存碎片。

        适合:老年代回收。

        标记--压缩算法:

        将存活对象重新排列到内存一端,将其他区域空间清理。

        进行标记-->清除-->压缩

        特点:移动对象

        适合:老年代回收,回收进来压缩,不会产生内存碎片,效率低。

        分代收集:

         根据不同区域特点进行各自回收。

        年轻代:对象生命周期短,存活对象少,回收频率高,采用复制算法。

        老年代:对象生命周期长,存活对象多,回收频率低,采用清除和压缩混合算法。

        三、相关概念
        1、内存溢出。

        经垃圾回收后,内存依然不够用,导致程序崩溃。

        2、内存泄漏。

        一个对象在程序中不会被使用,但垃圾收集器又不能回收,会一直占用着内存空间,久而久之也是造成内存器溢出的原因之一。

        3、Stop the World。

        指的是 GC 事件发生过程中,会产生应用程序的停顿。

        可达性分析算法中枚举根节点(GC Roots)会导致所有 Java 执行线程停顿,为什么需要停顿所有 Java 执行线程呢?

        当垃圾回收时(标记回收),会导致其他用户暂停,必须保证分析时其他程序不再运行,保证分析的准确性。

        四、垃圾回收器

        垃圾回收算法是理论,垃圾回收器是真正进行回收的实践者,不同厂商不同版本各自实现方式都不同。

        垃圾回收器分类:

        以线程分:

        单线程:适用于一些小设备,只有一个线程进行垃圾回收。

        多线程:有多个线程推进垃圾回收。

        以工作模式分:

        独占式:立即回收线程执行时,其他用户线程暂停执行。

        并发式:垃圾回收线程可以和用户线程同时执行。

        以工作区间分:

        年轻代垃圾回收器

        老年代垃圾回收器

        CMS(Concurrent Mark Sweep并发标记清除)

        是首个实现垃圾收集线程和用户线程同时执行的收集器。

        注意:不是所有都是并发执行,也有独占执行。

        垃圾回收过程

        初始标记:独占 会暂停用户线程。

        并发标记:并发 与用户线程同时执行。

        重新标记:独占 会暂停用户线程。

        并发清除:并发 与用户线程同时执行。

        G1(Garbage First)回收器

        适合大型服务器端,内存大,CPU更先进。

        将每个区域(伊甸园,幸存者,老年代)又划分成若干个小的区域,哪个区域垃圾数量多,优先回收哪个区域,可以做到整堆管理收集,也可以做到并发执行。

附:JVM详细操作流程图:

JVM(下)_第2张图片

你可能感兴趣的:(jvm)