JVM详解(类加载双亲委派模型垃圾回收JMM)

Posted 秃头小宝儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM详解(类加载双亲委派模型垃圾回收JMM)相关的知识,希望对你有一定的参考价值。

1.JVM简介

(1)JVM概念

  • JVM(Java Virtual Machine的简称。意为Java虚拟机
  • Java可以实现一次编写,到处运行。–>JVM(帮我们处理不同硬件之间的差异)Flutter

虚拟机:指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。
常见的虚拟机:JVM、VMwave、Virtual Box

(2)Java内存区域

JDK8:

①堆(线程共享)

:所有创建的对象信息都存放在这个区域,堆也是JVM中最大的一块内存。
堆里的数据划分

  • 1.新生代(Young区):新创建的数据会在新生代,当经历了一定次数的GC(垃圾回收),依然存活下来的数据,会移动到老年代(HotSpot默认的垃圾回收次数是 15次)
    新生代又分为三个区域:Eden、S0、S1(Eden+S0、Eden+S1)
  • 2.老年代(Old区):存放的是经过一定次数GC还存活的对象和大对象。

面试题:为什么大对象会直接存放在老年代?

:因为大对象的创建和销毁需要的时间比较多,所以性能也比较慢,如果存到新生代,那么可能会导致频繁的创建和销毁大对象,从而导致整个JVM运行效率的降低,所以直接将大对象存放到老年代。

②JVM栈(先进后出、线程私有)

③程序计数器(线程私有)

作用:用来记录线程的执行行号。

④本地方法栈(线程私有的)

作用:和JVM栈类似,只不过JVM栈是给Java程序使用的,而本地方法栈是给本地方法使用的。

⑤方法区(永久代)->元数据区(JDK1.8、线程共享)

字符串运行时常量池、常量final、类元数据

注意:JDK1.8的时候元空间存储到本地内存中,并且将字符串常量池放到堆中

2.JVM类加载过程(Class Loading)

  • 加载:将权限类名的二进制流加载到内存,在内存中生成方法入口。
  • 验证:验证加载的信息是否符合JVM规范(文件格式、字节码校验)。
  • 准备:加载静态变量赋值初始值。
  • 解析:是将符号引用替换成直接引用,也就是将常量进行初始化。
  • 初始化:JVM将执行权交给应用程序,此时要执行类的初始化方法。

3.JVM双亲委派模型(JDK1.2)

  • JVM加载子类不会直接进行类加载,而是将任务交给父类,一层一层的进行传递。如果找不到父类或者找不到此类,自己才会尝试加载。

    优势:唯一性(Object)、安全性

破环双亲委派模型:

  • 第一次:JDK1.2引入双亲委派模型,为了兼容老代码出现了第一次破环双亲委派模型。
  • 第二次:他是双亲委派模型自身的缺点所导致的第二次破坏,比如当父类出现了调用子类的方法的时候。
  • 第三次:人们对于热更新和热加载的最求。

4.JVM垃圾回收器

(1)判断死亡对象

①引用计数器算法

  • 计数器算法:给每个对象生成一个对应的计数器,每次在进行引用的时候,这个计数器+1,如果撤销引用时计数器-1,GC会根据计时器的值,当此值为0的时候就可以判定为此对象为死亡对象。
  • 引用计数器的缺点:不能解决循环引用的问题。

②可达性分析算法(目前JVM使用的判断对象死亡的算法)

核心思想为 : 通过一系列称为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称之为"引用链",当一个对象到GC Roots没有任何的引用链相连时(从GC Roots到这个对象不可达)时,证明此对象是不可用的。
JDK1.2之后有4种引用类型

(2)垃圾回收算法

①标记-清除算法

标记:用可达性分析算法
缺点:产生大量内存碎片

②复制算法

  • 性能比较快(新生代的垃圾回收算法)
  • 原理:先将存活的对象复制到另一个没有使用的内存中,然后再将此内存全部清除。
  • 复制算法的缺点:内存利用率不高。

③标记-整理算法

标记、整理:可以解决内存碎片的问题

(3)垃圾回收器

执行流程

1.初始标记(STW)
2.并发标记
3.重新标记(STW)
4.清除

5.Java内存模型(JMM)

JVM定义了一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。
主内存与工作内存之间的具体交互协议,JMM定义了8种方法:

  • lock(锁定) : 作用于主内存的变量,它把一个变量标识为一条线程独占的状态
  • unlock(解锁) : 作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可 以被其他线程锁定。
  • read(读取) :作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随 后的load动作使用。
  • load(载入) :作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量 副本中。
  • use(使用) :作用于工作内存的变量,它把工作内存中一个变量的值传递给执行引擎。
  • assign(赋值) :作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量。
  • store(存储) :作用于工作内存的变量,它把工作内存中一个变量的值传送到主内存中,以便后续的 write操作使用。
  • write(写入) :作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。

Java内存模型的三大特性

  • 原子性:由Java内存模型来直接保证的原子性变量操作包括read、load、assign、use、store和read。
  • 可见性:可见性是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。volatile、synchronized、final三个关键字可以实现可见性。
  • 有序性: 如果在本线程内观察,所有的操作都是有序的;

以上是关于JVM详解(类加载双亲委派模型垃圾回收JMM)的主要内容,如果未能解决你的问题,请参考以下文章

JVM详解(类加载双亲委派模型垃圾回收JMM)

JVM详解(类加载双亲委派模型垃圾回收JMM)

JVM基础详解

JVM基础详解

36.JVM内存分哪几个区,每个区的作用是什么如和判断一个对象是否存活java垃圾回收机制垃圾收集的方法有哪些java类加载过程类加载机制双亲委派Minor GC和Major GC

JVM ---- 大白话图文之JVM类加载机制内存区域垃圾回收