JVM 基础

目录

导图

总览

Java虚拟机运行时数据区

初识JVM

Java虚拟机的组成

字节码文件详解

正确打开字节码

字节码文件的组成

基础信息

常量池

方法

字节码常用工具的使用

类的生命周期

简介

加载阶段

连接阶段

验证

准备

解析

初始化阶段

类加载器

类加载器的分类

启动类加载器

默认加载器

双亲委派

机制

[打破双亲委派机制 *](#打破双亲委派机制 *)

自定义类加载器

线程上线文类加载器

Osgi框架的类加载器(了解)

JDK9之后的类加载器

总结

运行时数据区

程序计数器

栈

局部变量表

操作数栈

栈内存溢出

堆内存

方法区

实现

字符串常量池

直接内存

总结

自动垃圾回收

介绍

方法区的回收

堆回收

引用计数法和可达性分析法

五种对象引用

软引用

弱引用

虚引用和终结器引用

垃圾回收算法

评价标准

标记回收算法

复制算法

标记整理算法

分代垃圾回收算法-GC算法*

垃圾回收器

预热

[Serial 垃圾回收器](#Serial 垃圾回收器)

[年轻代 PaNew 垃圾回收器](#年轻代 PaNew 垃圾回收器)

[老年代 CMS 垃圾回收器](#老年代 CMS 垃圾回收器)

[年轻代 Parallel Scavenge 垃圾回收器-JDK8默认](#年轻代 Parallel Scavenge 垃圾回收器-JDK8默认)

[老年代 Parallel Old 回收器-JDK8默认](#老年代 Parallel Old 回收器-JDK8默认)

[G1 垃圾回收器-JDK9默认](#G1 垃圾回收器-JDK9默认)



导图

总览

初识JVM

然后将字节码交给计算机执行

Java虚拟机的组成

字节码文件详解

正确打开字节码

jclasslib工具的Github地址 : https://github.com/ingokegel/jclasslib

字节码文件的组成

基础信息

常量池

方法

字节码常用工具的使用

Arthas功能很强大,具体功能和命令可到官网查看
Arthas(阿尔萨斯)官网文档: https://arthas.aliyun.com/doc/

类的生命周期

简介

加载阶段

在代码使用反射获取对象信息就是在方法区中拿的

方法区中的 InstanceKlass 是C++编写的,无法Java语音调用,在堆区中转成Java类型的;

每个类在方法区和堆区中都分别对应一个 InstanceKlass 对象和 java.lang.Class 对象;

InstanceKlass保存类的元数据,java.lang.Class 对象是根据InstanceKlass生成的,是一个简化版的 InstanceKlass(去除了一些对开发者无用的元数据)

连接阶段

验证
准备
解析

初始化阶段

静态块在类被加载时执行,并且只执行一次,输出D

main方法执行第一行,输出A

初始化类Test1,先执行其他代码块后执行构造方法,输出CB

又初始化类Test1,先执行其他代码块后执行构造方法,输出CB

类加载器

类加载器的分类

启动类加载器
默认加载器

双亲委派

机制

其实就是自底向上查找是否加载过,自顶向下加载

打破双亲委派机制 *
自定义类加载器

线程上线文类加载器

DriverManager 是JDK提供的

Osgi框架的类加载器(了解)

JDK9之后的类加载器

总结

运行时数据区

程序计数器

随着线程被销毁,线程不共享的内存也会被释放


字节码指令写字节码文件中,当文件被加载之后字节码指令就会被保存在内存中,而程序计数器就算记录下一次执行的字节码指令所在的内存地址

栈

局部变量表

操作数栈

栈内存溢出

一般建议使用 -Xss 的方式设置

堆内存

方法区

实现

InstanceKlass 对象中的常量池和方法其实会额外开辟一个内存来存储,InstanceKlass对象只是存放了引用

字符串常量池


a + b 底层是 StringBuilder ,结果对象存放在堆中,所有上述代码结果是 false

而 "1" + "2" 在编译阶段会直接将其替换为 "12" , 而 "12" 在常量池冲存放,所有运行结果我 true

直接内存

当 jvm正在回收堆中对象的时候,如果用户正在使用我们的系统,可能会出现卡顿的情况

总结

**1、程序计数器:**每个线程会通过程序计数器记录当前要执行的的字节码指令的地址,程序计数器 可以控制程序指令的进行实现分支、跳转、异常等逻辑(不会出现内存泄漏)。

**2、虚拟机栈:**虚拟机栈采用栈的数据结构来管理 方法调用中的基本数据(局部变量、操作数等), 每一个方法的调用使用一个栈帧来保存。

**3、堆:**堆中存放的是创建出来的对象,这也是最容易产生内存溢出的位置。

**4、方法区:**方法区中主要存放的是类的元信息,同时还保存了常量池,JDK8是使用了元空间, 保存在直接内存。

自动垃圾回收

介绍

方法区的回收

堆回收

引用计数法和可达性分析法

五种对象引用

软引用
弱引用
虚引用和终结器引用

垃圾回收算法

评价标准
标记回收算法
复制算法
标记整理算法
分代垃圾回收算法-GC算法*

这个年轻代的GC用的是复制算法,这个S0和S1统称Survivor区

垃圾回收器

预热
Serial 垃圾回收器

年轻代 PaNew 垃圾回收器
老年代 CMS 垃圾回收器

只有在初始标记和重新标记中用户线程会停下来,且时间非常短

年轻代 Parallel Scavenge 垃圾回收器-JDK8默认
老年代 Parallel Old 回收器-JDK8默认
G1 垃圾回收器-JDK9默认


G1 垃圾回收器在 jdk8 相对成熟,但仍有不足之处,在 jdk9 中得到完善

相关推荐
江湖有缘16 小时前
Docker实战 | 使用Docker部署rmoments社交平台
jvm·docker·oracle
H.莓飛1 天前
【C++】内存管理
linux·开发语言·jvm·c++·visual studio
10mAh1 天前
【SQL】NOT IN 遇到 NULL 为什么返回空集?三值逻辑与反关联实战
jvm·数据库·sql
wuminyu1 天前
stackChunkOop内部结构与GC屏障的配合工作原理剖析
java·linux·c语言·jvm·c++
老三牛擦2 天前
订单履约流程
jvm
青春逝如流水2 天前
Java 线程在内存模型(JMM)与 JVM 实现:规范与落地的多元路径
java·开发语言·jvm·多线程·ai文章
colinu3 天前
C++ 异步任务与线程生命周期:`std::async`、`future`、`thread`、`jthread` 与协作式退出
java·jvm·c++
wuminyu3 天前
ForkJoinPool窃取线程在扫描其他WorkQueue时的随机采样算法与Phase线程挂起唤醒机制解析
java·linux·c语言·jvm·c++
DongQiShanRen3 天前
玄龙(上):TICK 主循环——意识心跳怎么跳
linux·jvm·数据库·人工智能·数据挖掘·rust
leisoo80973 天前
融资融券数据怎么查两融指标含义与杠杆观察方法 IG50免费开源股票数据API接口
开发语言·jvm·数据库·python·json