本系列相关链接

尚硅谷 宋红康 JVM教程_01_内存与垃圾回收篇——01 (20210103-20210110)

尚硅谷 宋红康 JVM教程_01_内存与垃圾回收篇——02 (20210111-20210117)

尚硅谷 宋红康 JVM教程_02_字节码与类的加载篇 (20210118~ )

todo 3 , 4

目录

尚硅谷 宋红康 JVM教程 https://www.bilibili.com/video/BV1PJ411n7xZ

ppt地址:

JVM参数列表: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

宋红康 mysql 高级篇 笔记 宋红康微博_JVM

P01-JVM内存与垃圾回收篇概述 09:34
P02-如何看待Java上层技术与JVM 20:17
P03-为什么要学习JVM 05:14
P04-面向人群和课程特点 10:15
P05-官方规范下载与参考书目 08:30
P06-跨平台的语言Java和跨语言的平台JVM 15:22
P07-字节码与多语言混合编程 06:25
P08-Java及JVM历史上的重大事件 14:10
P09-虚拟机与Java虚拟机介绍 08:59
P10-JVM的位置 03:44
P11-JVM的整体结构 06:24
P12-Java代码执行流程 05:17
P13-区分栈的指令集架构和寄存器的指令集架构 14:28
P14-JVM的生命周期 11:11
P15-SUN Classic VM的介绍 09:15
P16-Exact VM的介绍 03:18
P17-HotSpot VM的介绍 05:38
P18-JRockit VM的介绍 04:33
P19-IBM J9 VM的介绍 05:37
P20-KVM、CDC、CLDC的介绍 03:05
P21-Azul VM和BEA Liquid VM的介绍 03:04
P22-Apache Harmony的介绍 02:53
P23-Microsoft JVM和TaobaoJVM 05:34
P24-Dalvik VM及其他虚拟机的介绍 05:04
P25-Graal VM的介绍 03:14
P26-内存结构概述 08:44
P27-概述类的加载器及类加载过程 09:38
P28-类的加载过程一:Loading 04:33
P29-类的加载过程二:Linking 09:42
P30-类的加载过程三:Initialization 22:31
P31-几种类加载器的使用体会 13:23
P32-引导类、扩展类、系统类加载器的使用及演示 11:49
P33-为什么需要用户自定义类加载器及具体实现 08:19
P34-ClassLoader的常用方法及获取方法 05:30
P35-双亲委派机制的工作原理及演示 13:23
P36-双亲委派机制的优势 05:23
P37-沙箱安全机制 02:08
P38-类的主动使用与被动使用等 06:44
P39-运行时数据区内部结构 16:34
P40-JVM中的线程说明 05:34
P41-PC寄存器概述 11:04
P42-PC寄存器的使用举例 10:27
P43-解决PC寄存器两个面试问题 09:42
P44-虚拟机栈的主要特点 22:21
P45-虚拟机栈的常见异常与如何设置栈大小 11:43
P46-栈的存储结构和运行原理 25:34
P47-栈桢的内部结构 07:38
P48-局部变量表结构的认识 16:14
P49-字节码中方法内部结构的剖析 13:24
P50-变量槽slot的理解与演示 14:02
P51-静态变量与局部变量的对比及小结 09:01
P52-操作数栈的特点 11:43
P53-涉及操作数栈的字节码指令执行分析 16:11
P54-栈顶缓存技术 08:56
P55-动态链接的理解与常量池的作用 18:24
P56-方法的绑定机制:静态绑定与动态绑定 16:03
P57-4种方法调用指令区分非虚方法与虚方法 17:41
P58-invokedynamic指令的使用 11:15
P59-方法重写的本质与虚方法表的使用 15:35
P60-方法返回地址的说明 14:18
P61-栈桢中的一些附加信息 00:57
P62-虚拟机栈的5道面试题 23:19
P63-本地方法接口的理解 18:14
P64-本地方法栈的理解 08:17
P65-JVM学习路线与内容回顾 14:35
P66-堆空间的概述_进程中堆的唯一性 15:28
P67-堆空间关于对象创建和和GC的概述 17:38
P68-堆的细分内存结构 12:59
P69-堆空间大小的设置和查看 21:29
P70-OOM的说明与举例 09:40
P71-新生代与老年代中相关参数的设置 20:37
P72-图解对象分配的一般过程 18:25
P73-对象分配的特殊情况 06:38
P74-代码举例与JVisualVM演示对象的分配过程 05:38
P75-常用优工具概述与Jprofiler的演示 04:01
P76-MinorGC、MajorGC和FullGC的对比 17:26
P77-GC举例与日志分析 09:28
P78-体会堆空间分代的思想 05:09
P79-总结内存分配策略 12:56
P80-堆空间为每个线程分配的TLAB 09:55
P81-小结堆空间的常用参数设置 18:45
P82-通过逃逸分析看堆空间的对象分配策略 18:43
P83-代码优化之栈上分配 07:46
P84-代码优化之同步省略 04:58
P85-代码优化之标量替换 06:49
P86-代码优化及堆的小结 06:31
P87-方法区概述_栈堆方法区间的交互关系 11:42
P88-方法区的基本理解 17:27
P89-Hotspot中方法区的演进 09:37
P90-设置方法区大小的参数 14:52
P91-OOM:PermGen和OOM:Metaspace举例 09:58
P92-方法区的内部结构1 21:14
P93-方法区的内部结构2 08:13
P94-class文件中常量池的理解 18:12
P95-运行时常量池的理解 06:38
P96-图示举例方法区的使用 16:45
P97-方法区在jdk6、jdk7、jdk8中的演进细节 25:21
P98-StringTable为什么要调整位置 05:27
P99-如何证明静态变量存在哪 11:15
P100-方法区的垃圾回收行为 11:10
P101-运行时数据区的总结与常见大厂面试题说明 06:25
P102-对象实例化的几种方式 10:05
P103-字节码角度看对象的创建过程 06:12
P104-对象创建的六个步骤 22:07
P105-对象的内存布局 11:00
P106-对象访问定位 07:48
P107-直接内存的简单体验 07:53
P108-使用本地内存读写数据的测试 07:49
P109-直接内存的00M与内存大小的设置 10:44
P110-执行引擎的作用及工作过程概述 18:47
P111-Java程序的编译和解释运行的理解 10:11
P112-机器码_指令_汇编_高级语言理解与执行过程 15:40
P113-解释器的使用 11:00
P114-HotspotVM为何解释器与JIT编译器并存 17:32
P115-热点代码探测确定何时JIT 16:53
P116-Hotspot设置模式_C1与C2编译器 15:20
P117-Graal编译器与AOT编译器 07:41
P118-String的不可变性 21:34
P119-String底层Hashtable结构的说明 15:57
P120-String内存结构的分配位置 09:46
P121-两个案例熟悉String的基本操作 11:20
P122-字符串拼接操作的面试题讲解 14:01
P123-字符串变量拼接操作的底层原理 17:21
P124-拼接操作与append操作的效率对比 10:01
P125-intern()的理解 11:46
P126-new String()到底创建了几个对象 12:25
P127-关于intern()的面试难题 13:40
P128-面试的拓展问题 06:21
P129-intern()的课后练习1 08:05
P130-intern()的课后练习2 04:04
P131-intern()的空间效率测试 12:31
P132-StringTable的垃圾回收测试 05:32
P133-G1垃圾收集器的String去重操作 08:38
P134-垃圾回收相关章节的说明 08:18
P135-什么是GC,为什么需要GC 19:45
P136-了解早期垃圾回收行为 04:08
P137-Java自动内存管理介绍 08:11
P138-垃圾回收相关算法概述 09:17
P139-引用计数算法的原理及优缺点 13:47
P140-Java代码举例_Python的引用计数实施方案 08:25
P141-可达性分析算法与GC Roots 12:41
P142-对象的finalization机制 18:34
P143-代码演示可复活的对象 07:37
P144-使用MAT查看GC Roots 13:42
P145-使用JProfiler进行GC Roots溯源 06:38
P146-使用JProfiler分析OOM 03:32
P147-标记-清除算法原理及优缺点 16:08
P148-复制算法原理及优缺点 14:01
P149-标记-压缩算法原理及优缺点 11:16
P150-不同指标上对比三种算法 04:38
P151-分代收集算法的说明 12:36
P152-增量收集算法原理及优缺点 09:14
P153-分区算法的说明 03:59
P154-垃圾回收相关概念的概述 10:11
P155-System.gc()的理解 08:47
P156-手动gc理解不可达对象的回收行为 10:18
P157-内存溢出的分析 11:40
P158-内存泄漏的分析 13:04
P159-StopTheWorld事件的理解 10:57
P160-程序的并行与并发 06:33
P161-垃圾回收的并行与并发 03:39
P162-安全点与安全区域的说明 09:01
P163-Java中几种不同引用的概述 10:54
P164-强引用:不回收 06:35
P165-软引用:内存不足即回收 16:30
P166-弱引用:发现即回收 08:02
P167-虚引用:对象回收跟踪 13:29
P168-终结器引用的介绍 01:45
P169-垃圾回收器章节概览 05:07
P170-垃圾回收器的分类 15:31
P171-GC性能指标的整体说明 09:16
P172-吞吐量与暂停时间的对比说明 09:41
P173-垃圾回收器的发展迭代史 17:06
P174-垃圾回收器的组合关系 12:49
P175-如何查看默认的垃圾回收器 06:22
P176-Serial与Serial Old垃圾回收器的介绍 08:54
P177-如何设置使用Serial垃圾回收器 04:43
P178-ParNew垃圾回收器的介绍 07:22
P179-如何设置使用ParNew垃圾回收器 03:58
P180-Parallel与Parallel Old垃圾回收器的介绍 08:56
P181-Parallel垃圾回收器的相关参数设置 17:29
P182-CMS垃圾回收器概述与工作原理 12:45
P183-CMS的特点与弊端分析 15:58
P184-CMS垃圾回收器的参数设置 09:06
P185-CMS的小结及后续JDK版本中的变化 03:45
P186-认识G1垃圾回收器 14:52
P187-G1垃圾回收器的优势和不足 20:24
P188-G1的参数设置 09:12
P189-G1在生产环境的适用场景 03:58
P190-region的使用介绍 11:36
P191-G1垃圾回收器的主要回收环节 08:14
P192-记忆集与写屏障 08:24
P193-G1垃圾回收过程的详细说明 24:16
P194-G1垃圾回收的优化建议 04:11
P195-7种经典的垃圾回收器总结与调优建议 14:02
P196-常用的显示GC日志的参数 13:30
P197-GC日志中垃圾回收数据的分析 09:03
P198-举例说明日志中堆空间数据如何解读 10:16
P199-日志分析工具的使用 07:29
P200-新时期的Epsilon和Shenandoah垃圾回收器 13:21
P201-革命性的ZGC的性能介绍 09:03
P202-其他的厂商的垃圾回收器 01:41
P203-最后寄语 09:42
P204-JVM中篇内容概述 11:51
P205-字节码文件的跨平台性 13:12
P206-了解Java的前端编译器 08:30
P207-透过字节码看代码执行细节举例1 11:15
P208-透过字节码看代码执行细节举例2 03:51
P209-透过字节码看代码执行细节举例3 11:52
P210-解读Class文件的三种方式 15:47
P211-Class文件本质和内部数据类型 15:58
P212-Class文件内部结构概述 08:00
P213-字节码数据保存到excel中的操作 07:28
P214-Class文件的标识:魔数 06:33
P215-Class文件版本号 09:40
P216-常量池概述 05:50
P217-常量池计数器 03:53
P218-常量池表中的字面量和符号引用 15:49
P219-解析得到常量池中所有的常量 16:34
P220-常量池表数据的解读1 10:31
P221-常量池表数据的解读2 10:53
P222-常量池表项数据的总结 08:13
P223-访问标识 08:20
P224-类索引、父类索引、接口索引集合 07:41
P225-字段表集合的整体理解 08:13
P226-字段表数据的解读 12:01
P227-方法表集合的整体理解 06:51
P228-方法表数据的解读 10:48
P229-属性表集合的整理理解 04:47
P230-方法中Code属性的解读 13:44
P231-LineNumberTable和LocalVariableTable属性的解读 21:34
P232-SourceFile属性的解读 07:45
P233-Class文件结构的小结 03:42
P234-javac -g操作的说明 13:21
P235-javap主要参数的使用 21:16
P236-javap解析得到的文件结构的解读 21:19
P237-javap使用小结 05:05
P238-字节码指令集的概述 14:33
P239-指令与数据类型的关系及指令分类 10:11
P240-加载与存储指令概述 08:12
P241-再谈操作数栈与局部变量表 07:24
P242-局部变量压栈指令 08:44
P243-常量入栈指令 14:13
P244-出栈装入局部变量表指令 14:25
P245-算术指令及举例 20:37
P246-算法指令再举例 06:23
P247-彻底搞定++运算符 08:15
P248-比较指令的说明 02:46
P249-宽化类型转换 17:32
P250-窄化类型转换 18:50
P251-创建类和数组实例的指令 16:11
P252-字段访问指令 11:21
P253-数组操作指令 12:14
P254-类型检查指令 04:18
P255-方法调用指令 15:35
P256-方法返回指令 07:51
P257-操作数栈管理指令 19:20
P258-比较指令 08:29
P259-条件跳转指令 23:00
P260-比较条件跳转指令 08:16
P261-多条件分支跳转指令 14:11
P262-无条件跳转指令 15:33
P263-抛出异常指令 14:07
P264-异常处理与异常表 24:25
P265-同步控制指令 24:14
P266-类的生命周期概述 15:57
P267-加载完成的操作及二进制的获取方式 07:24
P268-类模型与Class实例的位置 08:19
P269-链接之验证环节 13:41
P270-链接之准备环节 11:15
P271-链接之解析环节 11:58
P272-初始化过程与类初始化方法 08:46
P273-初始化阶段赋值与准备阶段赋值的对比 26:33
P274-类初始化方法clinit()的线程安全性 07:02
P275-何为类的主动使用和被动使用 04:03
P276-类的主动使用1 08:00
P277-类的主动使用2 13:54
P278-类的主动使用3 11:43
P279-类的主动使用4 07:46
P280-类的被动使用 14:11
P281-类的使用介绍 04:59
P282-类的卸载相关问题 15:47
P283-类加载器的概述 12:35
P284-命名空间与类的唯一性 15:57
P285-类的加载器的分类 07:32
P286-引导类加载器的说明 09:02
P287-扩展类加载器的说明 06:17
P288-系统类加载器的说明 04:53
P289-用户自定义类加载器的说明 02:09
P290-测试不同类使用的类加载器 09:10
P291-ClassLoader与Launcher的初步剖析 11:50
P292-ClassLoader的源码解析1 15:04
P293-ClassLoader的源码解析2 07:08
P294-ClassLoader子类的结构剖析 05:16
P295-双亲委派机制的优势与劣势 22:02
P296-三次双亲委派机制的破坏 15:32
P297-热替换的代码实现 07:16
P298-沙箱安全机制 05:36
P299-自定义类加载器的好处和应用场景 05:43
P300-自定义类加载器的代码实现 15:57
P301-Java9的新特性 15:13

简介

宋红康 mysql 高级篇 笔记 宋红康微博_Java_02

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_03


宋红康 mysql 高级篇 笔记 宋红康微博_Java_04

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_05

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_06

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_07

宋红康 mysql 高级篇 笔记 宋红康微博_Java_08

一、JVM 与 Java体系结构

P01-JVM内存与垃圾回收篇概述 09:34

P02-如何看待Java上层技术与JVM 20:17

P03-为什么要学习JVM 05:14

面试的需要(BATJ,TMD,PKQ)
中高级程序要必备技能
追求极客精神:

P04-面向人群和课程特点 10:15

理论时间 大于 代码时间
图解

P05-官方规范下载与参考书目 08:30

oracle 官方地址 : https://docs.oracle.com/javase/specs/

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_09


周志明: 深入理解JAVA虚拟机

宋红康 mysql 高级篇 笔记 宋红康微博_Java_10

oracle 自己发布JAVA虚拟机 hotSpot

P06-跨平台的语言Java和跨语言的平台JVM 15:22

https://www.tiobe.com/tiobe-index/

宋红康 mysql 高级篇 笔记 宋红康微博_Java_11

JVM 是跨语言的平台

从JAVA7开始,JAVA虚拟机的设计者通过JSR-292规范实现“Java虚拟机平台上运行非Java语言编写的程序”

java7----2011年7月发布

java 不是最强大的语言,但是JVM是最强大的虚拟机。

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_12

P07-字节码与多语言混合编程 06:25

Java虚拟机从“JAVA虚拟机”向“JVM虚拟机”发展。
自己动手写JAVA虚拟机----资料介绍—据说20天左右

宋红康 mysql 高级篇 笔记 宋红康微博_Java_13

P08-Java及JVM历史上的重大事件 14:10

1990, JamesGosling 命名Oak,后改名Java
1995, Java首次公开亮相
1996, Jdk1.0 发布
1998, jdk1.2
2000, jdk1.3
2002, jdk1.4 (微软的.net发布)
2004, jdk 1.5 jdk 1.5 改名 JavaSE 5.0 (5.0是很大的改动)
2006, jdk 6
2007, Cljure
2008, Oracle收购BEA,得到 JRocket 虚拟机
2009, Twitter 改版 ,将程序从Ruby 改为 Scala
2010, Oracle 收购 Sun(74亿美元),Oracle 获得了HotSpot虚拟机 ,JCP组织进项管理java语言
2011 jdk7 {启用G1垃圾回收器}
2017 jdk9
2018 jdk11 {启用ZGC垃圾回收器} , Android 的Java 侵权案判决, Google赔偿 Oracle 88亿美元(注意收购时候用了74亿美元)

P09-虚拟机与Java虚拟机介绍 08:59

虚拟机: 系统虚拟机,程序虚拟机

系统虚拟机:VMWare
程序虚拟机:Java虚拟机 (JVM: Java Virtual Machine) ,之前jvm运行的是JAVA字节码,现在jvm运行的字节码有多种,Scala ,Kotlin ,Groovy 等

P10-JVM的位置 03:44

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_14

JDK – JRE — JVM 关系

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_15

P11-JVM的整体结构 06:24

方法区、堆: 多线程共享

栈、本地方法栈、程序计数器: 每个线程独享一份

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_16

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_17

P12-Java代码执行流程 05:17

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_18

P13-区分栈的指令集架构和寄存器的指令集架构 14:28

  1. 基于栈是架构 : 结构简单,不用寻址,无需硬件支持,可移植性好
  2. 基于寄存器架构 :需要寻址,依赖硬件,可移植性差,更高效。

java的JVM是基于栈的架构,跨平台性好,指令集小,指令多,执行性能比基于寄存器架构方式差。

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_19

Build — Recompile

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_20

javap -v StackStruTest.class 反编译字节码文件 指令

C:\workspace\workspace_idea\jvmByAtguigu\chapter01\target\classes\com\tiza\jvm>javap -v StackStruTest.class

宋红康 mysql 高级篇 笔记 宋红康微博_Java_21

public static void main(String[] args) {
        int i = 2;
        int j = 3;
        int var10000 = i + j;
    }
Code:
      stack=2, locals=4, args_size=1
         0: iconst_2       ---------    常量2 
         1: istore_1       ---------    放到操作数栈索引位置1  
         2: iconst_3       ---------    常量3 
         3: istore_2       ---------    放到操作数栈索引位置2
         4: iload_1        ---------    加载  操作数栈索引位置1  也就是  i 
         5: iload_2        ---------    加载  操作数栈索引位置2  也就是  j
         6: iadd           ---------    求和
         7: istore_3       ---------    将结果k 保存在 操作数栈索引位置3  
         8: return         ---------
      LineNumberTable:

P14-JVM的生命周期 11:11

虚拟机启动 执行 退出
启动:
执行: 执行一个java程序的时候,实际执行的是一个叫做JAVA虚拟机的进程。
退出:

P15-SUN Classic VM的介绍 09:15

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_22

Sun Classic VM :
世界第一款商用Java虚拟机,JDK1.4 的时候,完全被淘汰了。
只提供解释器,
现在的hotspot内置了此虚拟机。

hotspot VM
执行引擎:编译器+JIT(及时编译器)+垃圾回收器

P16-Exact VM的介绍 03:18

Exact VM jdk1.2 时候 Sun 提供
编译器 与 解释器 混合使用工作模式

P17-HotSpot VM的介绍 05:38

HotSpot:

HotSpot 是由 Longview Technologies 这家公司设计的

1997年SUN公司收购了这家公司,2009年sun这家公司被oracle收购。

JDK1.3 的时候,Hotspot VM 成为默认虚拟机。

HotSpot 占有绝对的市场定位,称霸武林。

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_23

P18-JRockit VM的介绍 04:33

EBA 的JRockit : 专注于服务器端应用,不关注程序的相应时间,因此,JRockit内部不包含解释器实现。JRockit JVM 是世界最快的JVM .
2008年, BEA 被oracle 收购了,

P19-IBM J9 VM的介绍 05:37

IBM Technology for Java Virtual Machine == IT4J = J9
2017年,IBM发布了开源J9 VM ,命名OpenJ9 ,交给Eclipse基金会管理。
注意是开源了J9 VM ,并没有开源J9 的全部(JDK>JRE>JVM)

P20-KVM、CDC、CLDC的介绍 03:05

P21-Azul VM和BEA Liquid VM的介绍 03:04

Azul VM
BEA Liquid VM: 已经终止研发

P22-Apache Harmony的介绍 02:53

Apache Harmony: IBM 和 Intel 联合开发开源JVM 。在. jdk 1.5 ,jdk 1.6 平台可用 。

P23-Microsoft JVM和TaobaoJVM 05:34

Microsoft JVM: 微软在自己的机器上开发Microsoft JVM ,1997年sun公司告微软的Microsoft 侵权,微软赔钱,后来取消了Microsoft JVM 项目。
TaoBaoJVM: 升级的hotspot JVM .

P24-Dalvik VM及其他虚拟机的介绍 05:04

Android系统使用的虚拟机,Dalvik VM 只能称作虚拟机,不能称作“JAVA虚拟机”,因为它没有遵守JAVA虚拟机规范
它不能直接运行java的class文件
它是基于寄存器架构的,不是JVM的栈架构
执行的是编译后的dex(Dalvik Executable)文件。执行效率比较高。
android 5.0 支持 ART VM 和 Dalvik VM .

P25-Graal VM的介绍 03:14

如果有一天HotSpot被取代,Graal VM 希望最大。
Graal 兼容性比较强

二、 类加载子系统

P26-内存结构概述 08:44

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_24

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_25

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_26

P27-概述类的加载器及类加载过程 09:38

方法区:

  1. 存放加载的类信息
    2.存放运行时常量信息
    javap -v StackStruTest.class — 反编译class 文件

C:\workspace\workspace_idea\jvmByAtguigu\chapter01\target\classes\com\tiza\jvm>javap -v StackStruTest.class

在本地磁盘的 .class file 文件,加载到JVM中,放在方法区。

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_27

P28-类的加载过程一:Loading 04:33

类的加载过程
加载–》 链接–》 初始化

1.获取此类的二进制流
2.将此流放到方法区
3.在内存中生成一个代表此类的java.lang.Class对象,作为方法区这个类的各种数据访问入口。

P29-类的加载过程二:Linking 09:42

todo … 20200103

P30-类的加载过程三:Initialization 22:31

下载安装 jclasslib Bytecode Viewer

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_28


宋红康 mysql 高级篇 笔记 宋红康微博_JVM_29

P31-几种类加载器的使用体会 13:23

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_30

package com.tiza.jvm.chapter02;

/**
 * @author leowei
 * @date 2021/1/4  - 23:47
 */
public class ClassLoaderTest {
    public static void main(String[] args) {
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println("systemClassLoader = " + systemClassLoader);  //sun.misc.Launcher$AppClassLoader@14dad5dc


        //获取其上层:扩展类加载器
        ClassLoader extClassLoader = systemClassLoader.getParent();
        System.out.println("extClassLoader = " + extClassLoader);   //sun.misc.Launcher$ExtClassLoader@28d93b30

        // 获取上层类加载器
        ClassLoader parent = extClassLoader.getParent();
        System.out.println("parent = " + parent);  // null  实际是bootStrapLoader ,此类由虚拟机定义

        //用户自定义类  的 classloader
        ClassLoader userDefineClsClassLoader = ClassLoaderTest.class.getClassLoader();
        System.out.println("userDefineClsClassLoader = " + userDefineClsClassLoader);   //sun.misc.Launcher$AppClassLoader@14dad5dc

        //String类 使用引导类加载器进行加载  --->  java 的核心类库 都是用 Bootstrap引导类加载器加载的  
        ClassLoader strClassLoader1 = String.class.getClassLoader();
        System.out.println("strClassLoader1 = " + strClassLoader1);  //null
    }
}

P32-引导类、扩展类、系统类加载器的使用及演示 11:49

扩展类加载器加载 jre/lib/ext 目录下的类库

package com.tiza.jvm.chapter02;

import sun.misc.Launcher;
import sun.security.ec.CurveDB;

import java.net.URL;
import java.security.Provider;

/**
 * @author leowei
 * @date 2021/1/5  - 0:12
 */
public class ClassLoaderTest02 {
    public static void main(String[] args) {

        System.out.println("**************  启动类加载器  *************");
        URL[] urls = Launcher.getBootstrapClassPath().getURLs();
        for (URL element : urls) {
            System.out.println(element.toExternalForm());
        }

        //从上面路径中随意选择一个类,看看他的类加载器是什么:引导类加载器
        ClassLoader classLoader = Provider.class.getClassLoader();
        System.out.println("classLoader = " + classLoader);    // null

        System.out.println("************  扩展类加载器  *************");
        String extDirs = System.getProperty("java.ext.dirs");
        for (String path : extDirs.split(";")) {
            System.out.println("path = " + path);
        }

        //从上面路径中随意选择一个类,看看他的类加载器是什么:引导类加载器
        ClassLoader classLoader1 = CurveDB.class.getClassLoader();
        System.out.println("classLoader1 = " + classLoader1);    // sun.misc.Launcher$ExtClassLoader@330bedb4

    }
}

P33-为什么需要用户自定义类加载器及具体实现 08:19

高深技术,暂时 无需自己实现

P34-ClassLoader的常用方法及获取方法 05:30

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_31

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_32


宋红康 mysql 高级篇 笔记 宋红康微博_Java_33


获取ClassLoader的途径

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_34


package com.tiza.jvm.chapter02;

/**

  • @author leowei
  • @date 2021/1/5 - 0:36
    */
    public class ClassLoaderTest03 {
    public static void main(String[] args) {
// 1
 ClassLoader classLoader = null;
 try {
     classLoader = Class.forName("java.lang.String").getClassLoader();
 } catch (ClassNotFoundException e) {
     e.printStackTrace();
 }
 System.out.println("classLoader = " + classLoader);  // null 

 // 2.
 ClassLoader classLoader1 = Thread.currentThread().getContextClassLoader();
 System.out.println("classLoader1 = " + classLoader1);

 //3.
 ClassLoader classLoader2 = ClassLoader.getSystemClassLoader();
 System.out.println("classLoader2 = " + classLoader2);

 // 4.
 ClassLoader classLoader3 = classLoader2.getParent();
 System.out.println("classLoader3 = " + classLoader3);

/*
classLoader = null
classLoader1 = sun.misc.Launcher宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_35AppClassLoader@14dad5dc
classLoader3 = sun.misc.Launcher$ExtClassLoader@28d93b30
*/

}
}

P35-双亲委派机制的工作原理及演示 13:23

没有听懂,
自定义一个java.lang.String 的类,(此类同jdk中的包名及类名),正常执行,不会报错,执行的过程是,String类加载到 Class Loader 中,
step1: Application ClassLoader 委托 — (低优先级) 如果前两个都不Load ,就我来执行
step2: Extension ClassLoader 委托 ----(中优先级)如果此 ClassLoader 能够响应对应的包,就执行响应,如果不行,交给 Application ClassLoader
step3: BootStrap ClassLoader ------(高优先级)如果 此ClassLoader 能够响应对应的包,就执行响应,如果不行,交给 Extension ClassLoader

还是要再听听 。。。。

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_36

P36-双亲委派机制的优势 05:23

宋红康 mysql 高级篇 笔记 宋红康微博_Java_37

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_38

package java.lang;
/**
 * @author leowei
 * @date 2021/1/5  - 23:06
 * 由于 java.lang 是由 启动类加载器进行加载, 加载的时候发现没有main函数,所以报如下错误
 * java.lang.SecurityException: Prohibited package name: java.lang
 * 双亲委派机制优势
 * 1.避免类的重复加载
 * 2.保护程序安全,放置核心API 被随意篡改
 */
public class LeoStart {
    public static void main(String[] args) {
        System.out.println("------");
    }
}

P37-沙箱安全机制 02:08

沙箱安全机制:保证对java核心源代码的保护

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_39

P38-类的主动使用与被动使用等 06:44

宋红康 mysql 高级篇 笔记 宋红康微博_Java_40

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_41

03 运行时数据区概述及线程

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_42

P39-运行时数据区内部结构 16:34

宋红康 mysql 高级篇 笔记 宋红康微博_Java_43

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_44


java虚拟机定义了若干程序运行期间会使用到的运行时数据区,

其中有一些会随着虚拟机的启动而创建,随着虚拟机退出而销毁。

另外一些则与线程一一对应,这些线程对应的数据区域会随着线程开始和结束而创建和销毁。

每个线程: 独立包括程序计数器,栈,本地栈
线程间共享: 堆、对外内存(元空间、代码缓存、永久代)

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_45

P40-JVM中的线程说明 05:34

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_46

P41-PC寄存器概述 11:04

https://docs.oracle.com/javase/specs/jvms/se8/html https://www.oracle.com/downloads/ https://www.oracle.com/java/technologies/javase-downloads.html https://docs.oracle.com/javase/8/docs/ https://docs.oracle.com/javase/specs/index.html

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_47

https://docs.oracle.com/javase/specs/jvms/se8/html/index.html https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.1PC Register 用于存储程序当前运行位置,及将要运行的位置,也叫程序钩子

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_48

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_49

宋红康 mysql 高级篇 笔记 宋红康微博_Java_50

P42-PC寄存器的使用举例 10:27

演示此段代码,看效果

package com.tiza.jvm.chapter04;

/**
 * @author leowei
 * @date 2021/1/6  - 21:02
 */
public class PCRegisterTest {
    public static void main(String[] args) {
        int i=10;
        int j=20;
        int k=i+j;
        String str="abc";
        System.out.println(i);
        System.out.println(k);
    }
}

P43-解决PC寄存器两个面试问题 09:42

1.使用PC寄存器存储字节码指令地址有什么用?

2.为什么使用PC寄存器记录当前线程的执行地址?

宋红康 mysql 高级篇 笔记 宋红康微博_Java_51

并行:

并发:

05 虚拟机栈

P44-虚拟机栈的主要特点 22:21

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_52

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_53

(虚拟机架构两种方式: 基于栈的方式,基于寄存器的方式 )

由于跨平台性的设计,Java的指令都是根据栈来设计的,不同平台CPU架构不同,所以不能设计为基于寄存器的。

优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要更多的指令。栈是运行时的单位,而堆是存储的单位。

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_54

宋红康 mysql 高级篇 笔记 宋红康微博_Java_55

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_56

P45-虚拟机栈的常见异常与如何设置栈大小 11:43

JVM 中的异常: OutOfMemoryError , StackOverflowError

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_57

https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE

package com.tiza.jvm.chapter05;

/**
 * @author leowei
 * @date 2021/1/6  - 22:20
 *
 * 自循环调用会报   java.lang.StackOverflowError 的异常
 * 默认栈大小情况下            调用次数    11406
 * 设置虚拟机栈大小  256k      调用次数    2467     (-Xss256k)
 *
 *
 */
public class StackErrorTest {
    private static int count=1;
    public static void main(String[] args) {
        System.out.println(count);
        count++;
        main(args);
    }
}

P46-栈的存储结构和运行原理 25:34

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_58


宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_59

package com.tiza.jvm.chapter05;


/**
 * @author leowei
 * @date 2021/1/6  - 23:01
 */
public class StackFrameTest {
    public static void main(String[] args) {
        StackFrameTest stackTest = new StackFrameTest();
        stackTest.method1();
    }

    // 注意使用 javap -v ***.class 反编译 看效果 ,需要为public 方法,原理未知
    public void method1() {
        System.out.println("method1() 开始执行... ");
        method2();
        System.out.println("method1() 执行结束... ");
    }

    // 注意使用 javap -v ***.class 反编译 看效果 ,需要为public 方法,原理未知
    public int method2() {
        System.out.println("method2() 开始执行... ");
        int i = 10;
        i = (int) method3();
        System.out.println("method2() 执行结束... ");
        return i;
    }
    // 注意使用 javap -v ***.class 反编译 看效果 ,需要为public 方法,原理未知
    public double method3() {
        System.out.println("method3() 开始执行... ");
        double j = 20.0;
        System.out.println("method3() 执行结束... ");
        return j;
    }
}

P47-栈桢的内部结构 07:38

Stack Frame 包含五个部分

LV:Local Variables 局部变量表

OS: Operand Stack 操作数栈 (表达式栈)

DL:Dynamic Linking 动态链接库 (指向运行时常量池的方法引用)

RA:Return Address 方法返回地址 (方法正常退出或者异常退出的定义)

其他信息

宋红康 mysql 高级篇 笔记 宋红康微博_Java_60

P48-局部变量表结构的认识 16:14

Local variables : 局部变量表 也叫 局部变量数组 或者 本地变量表

P49-字节码中方法内部结构的剖析 13:24

P50-变量槽slot的理解与演示 14:02

package com.tiza.jvm.chapter05;

import java.util.Date;

/**
 * @author leowei
 * @date 2021/1/7  - 22:47
 */
public class LocalVariablesTest {
    private int count=0;
    public static void main(String[] args) {
        LocalVariablesTest test = new LocalVariablesTest();
        int num=10;
        test.test1();

    }
    public LocalVariablesTest(){

    }



    public void test1(){
        Date date = new Date();
        String name1 = "atguigu.com";
        test2(date,name1);   //String info=
        System.out.println(date+name1);
    }

    public String test2(Date dateP,String name2){
        dateP =null;
        name2="songhongkang";
        double weight =130.5;
        char gendar ='男';
        return name2;
    }

    public void test4() {
        int a = 0;
        {
            int b = 0;
            b = a + 1;
        }
        //变量c,使用的是之前已经销毁的变量b占据的slot的位置 
        int c = a + 1;
    }

}

P51-静态变量与局部变量的对比及小结 09:01

P52-操作数栈的特点 11:43

P53-涉及操作数栈的字节码指令执行分析 16:11

todo … 20210108

P54-栈顶缓存技术 08:56

P55-动态链接的理解与常量池的作用 18:24

动态链接: 指向运行时常量池的方法引用

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_61

P56-方法的绑定机制:静态绑定与动态绑定 16:03

方法的调用:
静态链接, 动态链接
早期绑定, 晚期绑定
非虚方法, 虚方法

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_62

P57-4种方法调用指令区分非虚方法与虚方法 17:41

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_63

虚拟机中的几个方法调用指令:

  1. invokestatic: 调用静态方法,
  2. invokespecial: 调用《init》方法,私有及父类方法,
  3. invokevirtual: 调用所有虚方法
  4. invokeinterface: 调用接口方法
  5. invokedynamic: 动态解析需要调用的方法(jdk1.7)

非虚方法: 静态方法、私有方法、final方法、实例构造器、父类方法 (总结private final static )
虚方法: 其他方法。。

P58-invokedynamic指令的使用 11:15

P59-方法重写的本质与虚方法表的使用 15:35

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_64

java.lang.IllegalAccessError

java.lang.AbstractMethodError

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_65


宋红康 mysql 高级篇 笔记 宋红康微博_JVM_66


宋红康 mysql 高级篇 笔记 宋红康微博_Java_67


宋红康 mysql 高级篇 笔记 宋红康微博_JVM_68

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_69

P60-方法返回地址的说明 14:18

方法返回地址: return address , 存放调用改方法的PC寄存器的值。

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_70


宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_71

package com.tiza.jvm.chapter05;

import java.io.FileReader;
import java.io.IOException;
import java.util.Date;

/**
 * @author leowei
 * @date 2021/1/9  - 8:40
 */
public class ReturnAddressTest {
    public char methodChar(){return  'a';}
    public int methodInt(){return  0;}
    public long methodLong(){return  0L; };
    public float methodFloat(){return 0.0f;}
    public double methodDouble(){ return 0.0;}
    public String methodString(){ return  null;}
    public Date methodDate(){return null;}

    static {
        int i=10;
    }

    public void method2(){
        try {
            method1();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void method1() throws IOException{
        FileReader fis = new FileReader("leavingTiza.txt");
        char[] cBuffer =new char[1024];
        int len;
        while((len=fis.read(cBuffer)) != -1){
            String str = new String(cBuffer, 0, len);
            System.out.println(str);
        }
        fis.close();
    }
}

P61-栈桢中的一些附加信息 00:57

宋红康 mysql 高级篇 笔记 宋红康微博_Java_72

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_73

所以垃圾回收是否会涉及到虚拟机栈? 不会的!

P62-虚拟机栈的5道面试题 23:19

最后8分钟的线程安全与否,搞不懂 。

栈溢出: StackOverflowError

通过-Xss设置栈的大小

06 本地方法接口

P63-本地方法接口的理解 18:14

Native Method: 一个java调用一个非Java代码接口 。

示例: java接口调用c语言类库

本地方法没有方法体。

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_74

宋红康 mysql 高级篇 笔记 宋红康微博_Java_75

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_76

07 本地方法栈

P64-本地方法栈的理解 08:17

Native Method Stack
java虚拟机栈 用于管理Java方法的调用, 本地方法栈用于管理本地方法的调用。
本地方法是用c c++ … 语言编写的

本地方法栈 ,方法区 : 是HotSpot虚拟机特有的,不是所有虚拟机都有这两个区域。

宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_77

P65-JVM学习路线与内容回顾 14:35

宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_78


宋红康 mysql 高级篇 笔记 宋红康微博_宋红康 mysql 高级篇 笔记_79

08 堆

P66-堆空间的概述_进程中堆的唯一性 15:28

宋红康 mysql 高级篇 笔记 宋红康微博_Java_80


宋红康 mysql 高级篇 笔记 宋红康微博_垃圾回收器_81

宋红康 mysql 高级篇 笔记 宋红康微博_JVM_82

方法区与堆,都是进程共享的,一个进程对应一个 JVM 实例

一个进程中的多个线程共享 堆及方法区,

每个线程,有一组 虚拟机栈、本地方法栈、程序计数器

Java堆区在JVM启动的时候就创建了,其空间大小就确定了。是JVM管理的最大内存空间。堆内存大小是可以调节的。

宋红康 mysql 高级篇 笔记 宋红康微博_Java_83


C:\developer_tools\Java\jdk1.8.0_45\bin