JVM(解读Java 虚拟机)

JVM学习笔记

  • 3.双亲委派机制(类加载器涉及双亲委派机制)
  • 4. 运行时数据区(堆:Heap Area)
    • 6.4.1 标记阶段:引用计数算法、可达性分析算法
      • 6.4.1.1. 引用计数算法
      • 6.4.1.2. 可达性分析算法
    • 6.4.2 清除阶段:标记-清除算法、复制算法、标记-压缩算法
      • 6.4.2.1 标记-清除算法(Mark-Sweep算法)
      • 6.4.2.2 复制算法 (新生代S0和S1区)
      • 6.4.2.3 标记-压缩算法(Mark-Compact)
  • 7. 垃圾回收器(待更新...)
    • 7.0 垃圾回收器的分类:
    • 7.1 Serial收集器(单线程、 复制算法):
    • 7.2 ParNew收集器 (Serial+多线程):
    • 7.3 Parallel Scavenge收集器 (多线程复制算法、高效):
    • 7.4 Serial Old收集器 (单线程标记整理算法):
    • 7.5 Parallel Old收集器 (多线程标记整理算法):
    • 7.6 CMS(Concurrent Mark Sweep)收集器(多线程标记清除算法):
    • 7.7 G1(Garbage First)收集器 (标记-整理算法):

1. JVM整体结构

学习JVM的目的:性能调优

1.1. 字节码文件

源代码通过编译器生成.class字节码文件

1.2. 类加载器

1.2.1 加载 Loading

类加载器包括:引导类加载器(BootStrap ClassLoader)、扩展类加载器(Extension ClassLoader)、应用类加载器(Application ClassLoader)

1.引导类加载器(BootStrap ClassLoader启动类加载器):用来加载Java的核心库
/jre/lib/jar包、resource.jar包。负责扩展类加载器和应用类加载器,并指定为
他们的父类加载器。
2.扩展类加载器:java编写,间接派生于ClassLoader类,父类加载器为启动类加载
器。从在JDK的安装目录jre/lib/ext子目录(扩展目录)下加载类库。用户创建的jar
放在此目录下,也会自动由扩展类加载器加载。
3.应用程序类加载器:该类加载是程序中默认的类加载器,一般来说,java应用的类
都是由它完成加载的。
4.自定义加载器:通过继承抽象类Java.lang.ClassLoader类的方式,实现自己的类
加载器,以满足一些特殊的需求。

1.2.2 链接 Linking

Linking 包含三个环节:验证Verify、准备Prepare、解析Reslove

1.2.3 初始化 Initialization

静态变量的初始化

1.3. 运行时数据区 Runtime Data Area

1.3.1 程序计数器

程序计数器:存储指向下一条指令的地址。

程序计数器不存在GC 和 OOM.
除了程序计数器外,其他几个运行时区域的都有可能发生OutOfMemmoryError

1.3.2 虚拟机栈

  1. 虚拟机栈存储着以下内容:栈帧(局部变量表、动态链接、方法返回地址)
  2. 虚拟机栈描述的是Java方法执行的线程内存模型。

1.3.3 本地方法栈

本地方法栈:是为虚拟机使用的本地方法服务。

本地方法栈和虚拟机栈发挥的作用相似的,虚拟机栈为虚拟机执行java方法服务,
而本地方法则是为了虚拟机使用到的本地方法服务。

1.3.4 堆

创建Java对象,存放对象实例。

1.3.5 方法区(Method Area)

方法区:存放被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

注:字符串常量池则存在于方法区。

1.4. 执行引擎

执行引擎:将运行时数据区的指令翻译成机器指令,供CPU执行。

1.4.1 解释器

1.4.2 即时编译器

1.4.3 垃圾回收器

问题:如果自己写一个Java虚拟机的话,主要考虑哪些结构?
答:类加载器和执行引擎

2. 类加载器子系统

2.1类加载器子系统的作用

2.2 类的加载过程

2.3 类的链接过程

2.4 类的初始化

初始化阶段:执行类构造器方法()的过程。

3.双亲委派机制(类加载器涉及双亲委派机制)

3.1 双亲委派机制工作原理

  1. 案例:自定义了一个String类,String str = new String(); 默认调用自定义的String. 蕴含着双亲委派机制。 

  2. 双亲委派机制工作原理: 

3.2 双亲委派机制优势

  1. 避免类的重复加载
  2. 保护程序安全,防止核心API被随意篡改。(自定义类:java.lang.String)

3.3 沙箱安全机制

4. 运行时数据区(堆:Heap Area)

4.1 堆的核心概述

  1. 描述该图 

  2. 所有的线程共享Java堆,在这里还可以划分线程私有的缓冲区(Thread Local Allocation Buffer)TLAB。
  3. java堆的描述:所有的对象实例以及数组都应该在运行时分配在堆上。
  4. 数组和对象永远不会存储在栈上,因为栈帧中保存引用,这个引用指向对象和数组在堆中的位置。
  5. 在方法结束后,堆中的对象不会立马移除,仅仅在垃圾收集的时候才会被移除。
  6. 堆是GC执行垃圾回收的重点区域。

4.2 堆的内存细分

大厂面试jdk8中内存有哪些变化? 堆空间的元空间

4.3 设置堆内存大小与OOM

1.设置堆空间大小的参数

-xms 用来设置堆空间(年轻代和老年代)的初始内存大小

-xmx 最大内存大小

4.4 年轻代与老年代

  1. 年轻代含:伊甸园Eden、Survivor 0(幸存者0区 From)、Survivor 1(To). 

  2. 参数设置 
    -XX: NewRatio 设置新生代与老年代的比例,默认值是2. 

  3. YGC / Minor GC
1. 当伊甸园区满时会触发 Minor GC
2. 年龄计数器age 达到上限阈值,需要晋升到老年代 (默认age = 15)
3. s0 : s1  = 1:1
4. 关于垃圾回收:频繁在新生区收集,很少在养老区收集,几乎不在永久区/元空间收集。

YGC触发时,幸存者会被动进行垃圾回收。

4. FGC / Full GC

老年区满时(或者存放大文件)触发FGC.

4.5 Minor GC、Major GC与Full GC区别

4.6 Full GC 触发机制

触发 Full GC执行的情况有5种:

5. 执行引擎

  1. 执行引擎的概述(视频110) 

  2. 执行引擎的工作流程 

  3. Java代码编译和执行的过程 

6. 垃圾回收算法 GC

6.1 什么是垃圾?

垃圾是指在运行程序中没有任何指针指向的对象。

6.2 为什么需要GC?

1 内存迟早会被消耗完、2 JVM将整理出的内存分配给新的对象(案例 买1w的苹果)、3 应用程序业务庞大,没有GC就不能保证应用程序的正常进行。

6.3 垃圾回收机制

  1. 内存泄漏:内存区由于程序员编码的问题忘记了被回收,导致内存泄漏, 长时间积累—>OOM.
  2. Java中自动内存管理。
  3. GC的作用区域:方法区(元空间)和堆。 程序计数器、java栈、本地方法栈 不存在GC. 程序计数器也不存在溢出OOM.

6.4 垃圾回收相关算法

6.4.1 标记阶段:引用计数算法、可达性分析算法

垃圾标记阶段:对象存活判断-----》对象存活的两种方式:上述的引用计数和可达性分析算法。

6.4.1.1. 引用计数算法

1 定义:对于每个对象保存一个整形的引用计数器属性,用于记录对象被引用的情况。

2 优点:实现简单,判断效率高、回收没有延时性。

3 缺点:存储空间的开销、时间开销 、 无法处理循环引用。

4 循环引用的案例:

6.4.1.2. 可达性分析算法

1 基本思想:

2 哪些对象可以作为GC Roots的对象:

1 虚拟机栈中引用的对象

2 方法区中的类静态属性引用的对象

3 方法区中常量引用的对象

4 本地方法栈JNI(Native方法)引用的对象

6.4.2 清除阶段:标记-清除算法、复制算法、标记-压缩算法

6.4.2.1 标记-清除算法(Mark-Sweep算法)

1 原理

2 案例

3 标记-清除算法的缺点

①2次遍历—>效率不算高;

②在进行GC的时候,需要停止整个应用程序,导致用户体验差;

③这种方式清理出来的·空闲空间内存是不连续的,产生内存碎片。需要维护一个空闲列表。

6.4.2.2 复制算法 (新生代S0和S1区)

1 原理

2 案例

3 复制算法的优缺点

注意适用场景:(存活对象少、垃圾对象多的情况下)大部分对象死亡,少量对象存活 复制到B区,----》新生代区 S0与S1区非常合适。

6.4.2.3 标记-压缩算法(Mark-Compact)

1 背景 :改进于标记-清除法。

2 原理

标记-压缩算法的最终效果等同于标记–清除算法执行后,再进行一次内存碎片整理。

3 优缺点

6.5 对比三种算法

7. 垃圾回收器(待更新…)

7.0 垃圾回收器的分类:

按线程数分 可以分为串行垃圾回收器和并行垃圾回收器。

适用场景:串行垃圾回收器—单CPU.

案例:

按工作模式分 可以分并发式垃圾回收器和独占式垃圾回收器

案例:

碎片处理方式分 可以压缩式和非压缩式垃圾回收器

按工作的内存空间分 可以分为年轻代和老年代垃圾回收器

评估GC的性能指标:

7.1 Serial收集器(单线程、 复制算法):

新生代单线程收集器,标记和清理都是单线程,优点是简单高效;

7.2 ParNew收集器 (Serial+多线程):

新生代收并行集器,实际上是Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现;

7.3 Parallel Scavenge收集器 (多线程复制算法、高效):

新生代并行收集器,追求高吞吐量,高效利用 CPU。吞吐量 = 用户线程时间/(用户线程时间+GC线程时间),高吞吐量可以高效率的利用CPU时间,尽快完成程序的运算任务,适合后台应用等对交互相应要求不高的场景;

7.4 Serial Old收集器 (单线程标记整理算法):

老年代单线程收集器,Serial收集器的老年代版本;

7.5 Parallel Old收集器 (多线程标记整理算法):

老年代并行收集器,吞吐量优先,Parallel Scavenge收集器的老年代版本;

7.6 CMS(Concurrent Mark Sweep)收集器(多线程标记清除算法):

老年代并行收集器,以获取最短回收停顿时间为目标的收集器,具有高并发、低停顿的特点,追求最短GC回收停顿时间。

7.7 G1(Garbage First)收集器 (标记-整理算法):

Java堆并行收集器,G1收集器是JDK1.7提供的一个新收集器,G1收集器基于“标记-整理”算法实现,也就是说不会产生内存碎片。此外,G1收集器不同于之前的收集器的一个重要特点是:G1回收的范围是整个Java堆(包括新生代,老年代),而前六种收集器回收的范围仅限于新生代或老年代。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值