JVM

本文详细介绍了JVM的体系结构,包括类加载器、内存模型和垃圾回收机制。类加载器分为Bootstrap、Extension和AppClassLoader,遵循双亲委派机制。JVM内存模型包括Execution Engine、Native Method Stack、PC寄存器、方法区和栈、堆。GC(垃圾回收)主要针对Young Generation、Tenure Generation和Permanent Space,通过清除、压缩和复制等方式进行回收。
摘要由CSDN通过智能技术生成

一、JVM体系

在这里插入图片描述JVM是运行在操作系统之上的,它与硬件没有直接的交互。

Java 虚拟机将运行时内存区域划分为五个部分,分别为

  • 方法区、堆、PC 寄存器、Java 方法栈和本地方法栈

转换的过程为通过编译器将 Java 程序转换成该虚拟机所能识别的指令序列,也称 Java 字节码。Java虚拟机会将字节码,即class文件加载到JVM中。由JVM进行解释和执行。
执行 Java 代码首先需要使用类加载器将它编译而成的 class 文件加载到 Java 虚拟机中。加载后的 Java 类会被存放于方法区(Method Area)中。实际运行时,虚拟机会执行方法区内的代码。
在虚拟机中,方法区和堆为线程共享,也是垃圾回收的重点照顾区域。栈空间为线程私有,基本不会出现垃圾回收。

二、类加载器

1. 类加载器简介

类加载器,即ClassLoader,它负责加载class文件。

2. 类加载器分类
虚拟机自带的类加载器:
  1. 启动类加载器(Bootstrap):主要负责加载jre中的最为基础、最为重要的类。如$JAVA_HOME/jre/lib/rt.jar等,以及由虚拟机参数
    -Xbootclasspath 指定的类。由于它由C++代码实现,没有对应的java对象,因此在java中,尝试获取此类时,只能使用null来指代。
  2. 扩展类加载器(Extension),由Java代码实现,用于加载相对次要、但又通用的类,比如存放在 JRE 的 lib/ext 目录下
    jar 包中的类,以及由系统变量 java.ext.dirs 指定的类。如$JAVA_HOME/jre/lib/ext/*.jar。
  3. 应用程序类加载器(AppClassLoader),由Java代码实现,
    它负责加载应用程序路径下的类。(这里的应用程序路径,便是指虚拟机参数 -cp/-classpath、系统变量
    java.class.path 或环境变量 CLASSPATH 所指定的路径。)默认情况下,应用程序中包含的类便是由应用类加载器加载的。
  4. 用户自定义的加载器:Java.lang.ClassLoader的子类,用户可以定制类的加载方式。例如可以对 class
    文件进行加密,加载时再利用自定义的类加载器对其解密。
3. 双亲委派机制

优势:

  1. 这采用双亲委派模式的是好处是Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次。
  2. 其次是考虑到安全因素,防止java核心api中定义类型不会被用户恶意替换和篡改,从而引发错误。

三、JVM的内存模型

在这里插入图片描述

Execution Engine

Execution Engine执行引擎负责解释命令,提交操作系统执行。

Native Method Stack

定义了很多调用本地操作系统的方法,也称之为本地方法接口。

PC寄存器(程序计数器)

每个线程都有一个程序计数器,是线程私有的,就是一个指针。

方法区(Method Area)

所有定义的方法的信息都保存在该区域,此区属于共享区间。
静态变量+常量+类信息(构造方法/接口定义)+运行时常量池存在方法区中。

8种基本类型的变量+对象的引用变量+实例方法都是在栈内存中分配。

堆内存逻辑上分为三部分:
Young Generation Space 新生区 Young/New
Tenure generation space 养老区 Old/ Tenure
Permanent Space 永久区(1.8后为元空间) Perm
Java7之前的逻辑设计

物理设计:
在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。

四、GC

1、GC分类:

GC按照回收的区域又分了两种类型,一种是普通GC(minor GC),一种是全局GC(major GC or Full GC)。

2、GC的工作特点

理论上GC过程中会频繁收集Young区,很少收集Old区,基本不动Perm区(元空间/方法区)。

引用计数法

引用计数法就是如果一个对象没有被任何引用指向,则可视之为垃圾。这种方法的缺点就是不能检测到循环指向的存在。

可达性分析(GC ROOTS算法)

简单理解,可以理解为堆外指向堆内的引用。

垃圾回收的三种方式
清除

第一种是清除(sweep),即把死亡对象所占据的内存标记为空闲内存,并记录在一个空闲列表(free list)之中。当需要新建对象时,内存管理模块便会从该空闲列表中寻找空闲内存,并划分给新建的对象。
两个缺点。一是会造成内存碎片。另一个则是分配效率较低。
在这里插入图片描述

压缩

第二种是压缩(compact),即把存活的对象聚集到内存区域的起始位置,从而留下一段连续的内存空间。这种做法能够解决内存碎片化的问题,但代价是压缩算法的性能开销。
在这里插入图片描述

复制

第三种则是复制(copy),即把内存区域分为两等分,分别用两个指针 from 和 to 来维护,并且只是用 from 指针指向的内存区域来分配内存。当发生垃圾回收时,便把存活的对象复制到 to 指针指向的内存区域中,并且交换 from 指针和 to 指针的内容。复制这种回收方式同样能够解决内存碎片化的问题,但是它的缺点也极其明显,即堆空间的使用效率极其低下。
在这里插入图片描述

总结

回收死亡对象的内存共有三种方式,分别为:会造成内存碎片的清除、性能开销较大的压缩、以及堆使用效率较低的复制。当然,现代的垃圾回收器往往会综合上述几种回收方式,综合它们优点的同时规避它们的缺点。

垃圾回收算法

  1. 标记复制(Mark-Copying)算法 口诀:复制必交换,谁空谁为to
  2. 标记清除(Mark-Sweep)算法
  3. 标记压缩(Mark–Compact)算法
  4. 标记清除压缩(Mark-Sweep-Compact)算法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值